Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • suzyb 474 posts 932 karma points
    Apr 20, 2017 @ 18:39
    suzyb
    1

    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:

    enter image description here

    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.

  • Dennis Adolfi 1082 posts 6449 karma points MVP 6x c-trib
    Apr 20, 2017 @ 19:16
    Dennis Adolfi
    0

    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!

  • suzyb 474 posts 932 karma points
    Apr 20, 2017 @ 19:57
    suzyb
    0

    The controller code is here

    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.

    And it's called like this

    @Html.Action("RenderMembershipForm", "MembershipFormSurface")
    

    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.

  • suzyb 474 posts 932 karma points
    Apr 21, 2017 @ 18:16
    suzyb
    101

    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 :(

  • nickornotto 403 posts 907 karma points
    Jul 21, 2020 @ 19:32
    nickornotto
    0

    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?

  • suzyb 474 posts 932 karma points
    Jul 21, 2020 @ 19:50
    suzyb
    1

    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.

    Sorry I can't help more.

  • nickornotto 403 posts 907 karma points
    Aug 10, 2020 @ 21:59
    nickornotto
    0

    Ok, thanks. I found a work around

  • Dennis Adolfi 1082 posts 6449 karma points MVP 6x c-trib
    Apr 21, 2017 @ 19:13
    Dennis Adolfi
    0

    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!

  • Trevor Morgan 13 posts 64 karma points
    Apr 26, 2019 @ 08:27
    Trevor Morgan
    0

    Just wanted to swing by and said this post helped me out @suzyb, thanks for updating with the solution!

  • Max 4 posts 74 karma points
    Feb 17, 2023 @ 23:28
    Max
    0

    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>

     "ModelsBuilder": {
        "ModelsMode": "SourceCodeAuto",
        "AcceptUnsafeModelsDirectory": true,
        "ModelsDirectory": "~/App_Data/Models",
        "DebugLevel": 0
      },
    

    )

    Then create the controller

     public class UserEnquiryController : SurfaceController
    {
        public UserEnquiryController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider) : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
        {
        }
    
        public IActionResult Index()
        {
            return View();
        }
    
        [HttpPost]
        public IActionResult SubmitForm(UserEnquiry model)
        {
            if (ModelState.IsValid)
            {
                TempData.Add("Success", "true");
    
            }
            else
            {
               var successKey = TempData.FirstOrDefault(t=>string.Equals("Sucess",t.Key, StringComparison.InvariantCultureIgnoreCase));
                if (successKey.Value != null)
                {
                    TempData.Remove(successKey);
                }
            }
            return CurrentUmbracoPage();
        }
    }
    

    And my view is below

    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.UserEnquiry>
    

    @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))

    @Html.GetGridHtml(Model, "mainContent", "Clean")
    @using (Html.BeginUmbracoForm("SubmitForm", "UserEnquiry")) { @if (submitted) {

        @if (success)
        {
            @Model.SuccessMessage
        }
        else
        {
            @Model.ErrorMessage
        }
    }
    else
    {
        @Model.IntroductionMessage
        <div class="my-5">
            @Html.Label(Model.UserEnquiryName)
            @Html.TextBox(Model.UserEnquiryName)
            @Html.Label(Model.UserEnquiryNumber)
            @Html.TextBox(Model.UserEnquiryNumber)
    
           <input type="submit" class="button" value="Submit" />
        </div>
    }
    

    }

Please Sign in or register to post replies

Write your reply to:

Draft