can only use UmbracoPageResult in the context of an Http POST error
I have a form on a site that I have tested many times without any issue. But of course when it is sent to the client for approval and they test it, they get the following error "can only use UmbracoPageResult in the context of an Http POST when using a SurfaceController form". The screen gran sent by the client is below:
Googling suggests this can happen if the Post method is named the same as the Get however this is not the case on my form.
The client mentioned he "refreshed" the form so I've been trying going back and forward through the form, refreshing with F5 yet and trying all sorts. Yet I cannot seem to reproduce the error. Does anyone have any idea what the problem could be.
public class MembershipFormSurfaceController : BaseMembershipFormSurfaceController
{
public MembershipFormSurfaceController()
{
}
[ChildActionOnly]
public ActionResult RenderMembershipForm()
{
MembershipFormViewModel model = new MembershipFormViewModel();
MembershipSettings membershipSettingsNode = Umbraco.TypedContentSingleAtXPath("/root/settings/membershipSettings") as MembershipSettings;
model.MembershipTypes = membershipSettingsNode.MembershipTypes;
return PartialView("Forms/_MembershipForm", model);
}
[HttpPost]
[ValidateAntiForgeryToken]
[MultipleButton(Name = "action", Argument = "Paypal")]
public ActionResult Paypal(MembershipFormViewModel viewModel)
{
return HandleMembershipForm(viewModel, PaymentMethodTypes.Paypal);
}
[HttpPost]
[ValidateAntiForgeryToken]
[MultipleButton(Name = "action", Argument = "DirectDebit")]
public ActionResult DirectDebit(MembershipFormViewModel viewModel)
{
return HandleMembershipForm(viewModel, PaymentMethodTypes.DirectDebit);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult HandleMembershipForm(MembershipFormViewModel viewModel, PaymentMethodTypes paymentMethod)
{
bool isSpam = false;
if (!ModelState.IsValid)
{
return CurrentUmbracoPage();
}
if (!string.IsNullOrWhiteSpace(viewModel.FormCheck)) { isSpam = true; }
if (!isSpam)
{
MembershipFormPage currentPage = Umbraco.AssignedContentItem as MembershipFormPage;
// Get any services required
var memberService = Services.MemberService;
var contentService = Services.ContentService;
// Get the settings node
Settings settingsNode = Umbraco.TypedContentSingleAtXPath("/root/settings") as Settings;
// Create the new member and assign all the form values to the member properties
IMember member = memberService.CreateMember(viewModel.FirstName + " " + viewModel.LastName, viewModel.EmailAddress, viewModel.FirstName + " " + viewModel.LastName, "Member");
member.IsApproved = true;
SetMemberProperties(member, viewModel);
SaveAttachment(member, viewModel);
memberService.Save(member);
memberService.AssignRole(member.Id, "Members");
memberService.Save(member);
// At this point we want to send the user to the PayPal system
if (member != null && member.Key != Guid.Empty)
{
// send an email to the admin to let them know about the application.
// I think this is better here before payment as it means admin will be notified of all signups even ones that quit out before paying (so they can chase or delete from CMS)
EmailService.SendApplicationEmails(member, currentPage);
switch (paymentMethod)
{
case PaymentMethodTypes.Paypal:
// Get the PayPal Provider page and forward the user to here using the correct membershipOrderReference, best to add the membership number for security
PayPalProvider payPalProviderNode = Umbraco.TypedContentSingleAtXPath("/root/settings/payPalProvider") as PayPalProvider;
Response.Redirect(payPalProviderNode.Url + "?membershipOrderReference=" + membershipOrder.OrderReference + "&membershipNumber=" + membershipOrder.MembershipNo);
break;
case PaymentMethodTypes.DirectDebit:
MembershipSettings membershipSettings = Umbraco.TypedContentSingleAtXPath("/root/settings/membershipSettings") as MembershipSettings;
Response.Redirect(membershipSettings.DirectDebitFormPage.Url + "?membershipOrderReference=" + membershipOrder.OrderReference + "&membershipNumber=" + membershipOrder.MembershipNo);
break;
}
}
}
return RedirectToCurrentUmbracoPage();
}
}
BaseMembershipFormSurfaceController inherits from SurfaceController and just contains a few helper methods.
I really don't know what the client is doing that is causing the error. Think I'm going to have to get the project manager to contact them and ask tbh.
With the help of a colleague I've discovered what is causing the problem. The client was skipping the javascript validation so server side was running (can't believe I never thought of that) and when it hit the CurrentUmbracoPage and tried to render the page again it threw the error.
I wasn't using Html.BeginUmbracoForm but a plain html form tag instead as I had followed this stack overflow post 1 to get multiple submit buttons working on the form. This seems to have confused Umbraco so it doesn't know how to route back to the page when there are errors.
Really annoying that I spend so long trying to figure out the issue when it was so obvious :(
I can't really remember this but from what I said, I simply changed the normal <form> tag to Html.BeginUmbracoForm instead so (I think) Umbraco knows how to route the post.
That was 3 years ago though so it would have been in an older version of Umbraco. Not even sure what version of Umbraco it would have been as I can't recall which project it was.
Ah, glad to hear that it worked out for you and thank you for posting the answer! Hopefully it can help someone in the future with the same problem. #h5yr
I have been looking for a way to hijack the umbraco form and customize it for awhile.
What helped me was the keyworkd BeginUmbracoForm when I was using BeginForm (being a MVC developer, I never thought of anything wrong with it).
So I am posting my code here, in case anyone needs help to successfully do so.
You need to make sure you can generate the model first via the appSettings.json (Under Umbraco>CMS>
can only use UmbracoPageResult in the context of an Http POST error
I have a form on a site that I have tested many times without any issue. But of course when it is sent to the client for approval and they test it, they get the following error "can only use UmbracoPageResult in the context of an Http POST when using a SurfaceController form". The screen gran sent by the client is below:
Googling suggests this can happen if the Post method is named the same as the Get however this is not the case on my form.
The client mentioned he "refreshed" the form so I've been trying going back and forward through the form, refreshing with F5 yet and trying all sorts. Yet I cannot seem to reproduce the error. Does anyone have any idea what the problem could be.
Hi! Could you post the code for your controller? Will have a look at it tomorrow, unless you figure it out before then.
Take care and good luck!
The controller code is here
BaseMembershipFormSurfaceController inherits from SurfaceController and just contains a few helper methods.
And it's called like this
I really don't know what the client is doing that is causing the error. Think I'm going to have to get the project manager to contact them and ask tbh.
With the help of a colleague I've discovered what is causing the problem. The client was skipping the javascript validation so server side was running (can't believe I never thought of that) and when it hit the CurrentUmbracoPage and tried to render the page again it threw the error.
I wasn't using Html.BeginUmbracoForm but a plain html form tag instead as I had followed this stack overflow post 1 to get multiple submit buttons working on the form. This seems to have confused Umbraco so it doesn't know how to route back to the page when there are errors.
Really annoying that I spend so long trying to figure out the issue when it was so obvious :(
You're not really talking what your solution was.
I am getting the same error while using the action button on the age but have no other forms on the page.
Sorry I don't get what is it that you changed that worked for you?
I can't really remember this but from what I said, I simply changed the normal
<form>
tag toHtml.BeginUmbracoForm
instead so (I think) Umbraco knows how to route the post.That was 3 years ago though so it would have been in an older version of Umbraco. Not even sure what version of Umbraco it would have been as I can't recall which project it was.
Sorry I can't help more.
Ok, thanks. I found a work around
Ah, glad to hear that it worked out for you and thank you for posting the answer! Hopefully it can help someone in the future with the same problem. #h5yr
Have a great weekend!
Just wanted to swing by and said this post helped me out @suzyb, thanks for updating with the solution!
Thank you Suzyb,
I have been looking for a way to hijack the umbraco form and customize it for awhile.
What helped me was the keyworkd BeginUmbracoForm when I was using BeginForm (being a MVC developer, I never thought of anything wrong with it). So I am posting my code here, in case anyone needs help to successfully do so.
You need to make sure you can generate the model first via the appSettings.json (Under Umbraco>CMS>
)
Then create the controller
And my view is below
@using Clean.Core.Models.ViewModels @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels
@{ Layout = "master.cshtml"; var submitted = false; if (bool.TryParse(TempData["Success"]?.ToString() ?? "", out var success)) { submitted = true; } }
@await Html.PartialAsync("~/Views/Partials/pageHeader.cshtml", new PageHeaderViewModel(Model.Name, Model.Title, Model.Subtitle, Model.MainImage))
}
is working on a reply...