Copied to clipboard

Flag this post as spam?

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


  • Tahir 13 posts 73 karma points
    Oct 05, 2016 @ 11:25
    Tahir
    0

    CurrentUmbracoPage error after post back

    Hi All,

    I need little help in understanding the SurfaceController, BeginUmbracoForm and CurrentUmbracoPage. Below is the code showing the error message.

    I have read this link but unable to figure out why still getting the error

    https://our.umbraco.org/documentation/Reference/Templating/Mvc/forms#UnderstandingtheRoutingProcess
    

    Any help will be appreciated.

    My Hijacked route controller

    public partial class MemberLoginController : Umbraco.Web.Mvc.RenderMvcController
    {
        public virtual ActionResult Index(MemberLogin model)
        {
            MemberLoginViewModel customModel = new MemberLoginViewModel();
            DocumentViewModel<MemberLogin, MemberLoginViewModel> viewModel = DocumentViewModelHelper.Create(model, customModel);
    
            return View(viewModel);
        }
    }
    

    My View

    @inherits WebViewPage<IDocumentViewModel<MemberLogin, MemberLoginViewModel>>
    @using (Html.BeginUmbracoForm("Login", "AccountManagementSurface", FormMethod.Post, new { @class = "form-horizontal", role = "form", returnUrl="/" }))
    {
        @Html.AntiForgeryToken()
        <input type="submit" value="Log in" class="btn btn-default" />
    }
    

    My Surface controller

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        // all good
        return RedirectToCurrentUmbracoPage();
    
        // any login errors
        return CurrentUmbracoPage(); // On this line, the MemberLoginController/Index gets called again (which is right), howvere, view gets the RenderModel as model and not DocumentViewModel<MemberLogin, MemberLoginViewModel>.
    }
    

    Error message

    return CurrentUmbracoPage(); // On this line, the MemberLoginController/Index gets called again (which is right), howvere, view gets the RenderModel as model and not DocumentViewModel<MemberLogin, MemberLoginViewModel>.
    
  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Oct 05, 2016 @ 13:27
    Ismail Mayat
    0

    Tahir,

    Does it work when you take out async on the Login method?

    Regards

    Ismail

  • Tahir 13 posts 73 karma points
    Oct 05, 2016 @ 16:48
    Tahir
    0

    Nope, it is still the same error....

  • Shannon Deminick 1524 posts 5270 karma points MVP 2x
    Oct 10, 2016 @ 07:39
    Shannon Deminick
    0

    Why are you trying to Model bind a MemberLogin model in your Index method? Generally, you shouldn't do this. There's been a lot of discussion about this in the past:

    The bound RenderModel on an action is the 'data source' for the request, it is not bound based on route parameters in the request, it is purely bound based on the content item that Umbraco has found during it's routing phase. You should not POST to a RenderMvcController directly so therefore you shouldn't really change these parameters. There are some corner cases such as if you are doing paging, or binding query string request parameters to this model (which will work too).

    I would suggest trying this without changing the bound RenderModel to MemberLogin, then you can create your MemberLogin model inside your action and pass whatever you want to your view.

  • Tahir 13 posts 73 karma points
    Oct 10, 2016 @ 10:00
    Tahir
    0

    Many thanks for replying.

    I have now changed the controller to

    public override ActionResult Index(RenderModel model)
    {
        MembershipRegisteration model2 = new MembershipRegisteration(model.Content);
        var viewModel = new MembershipRegisterationViewModel();
        var iewModel = DocumentViewModelHelper.Create(model2, viewModel);
    
        return CurrentTemplate(iewModel);
    
    }
    

    But still getting the same error message on

    return CurrentUmbracoPage(); // On this line, the MemberLoginController/Index gets called again (which is right), howvere, view gets the RenderModel as model and not DocumentViewModel<MemberLogin, MemberLoginViewModel>.
    
    Cannot bind source type ViewModels.DocumentViewModel`2[[Umbraco.Web.PublishedContentModels.MembershipRegisteration,],[ViewModels.MembershipRegisterationViewModel, ] to model type Umbraco.Web.Models.RenderModel`1[[Umbraco.Web.PublishedContentModels.MembershipRegisteration,*]].
    

    Just to add my layout view is

    @inherits WebViewPage<ViewModels.IDocumentViewModel<ISiteBase, IViewModelBase>>
    

    and the view for the page is

    @model ViewModels.RegisterViewModel
    

    You should not POST to a RenderMvcController directly

    That is right, All the postbacks are done to a seperate surfacecontroller.

    so therefore you shouldn't really change these parameters.

    So effectively what you are saying is, in general, all controllers (Index Action) inheriting from RenderMvcController should accept RenderModel as parameters.

  • Shannon Deminick 1524 posts 5270 karma points MVP 2x
    Oct 10, 2016 @ 10:10
    Shannon Deminick
    0

    So effectively what you are saying is, in general, all controllers (Index Action) inheriting from RenderMvcController should accept RenderModel as parameters.

    yes... in nearly all cases there is no reason to change this.

    Sounds like you should start debugging this by simplifying things to see where the error comes from. Is this occurring because of your Layout page's model declaration and/or because of your view's model declaration?

  • Tahir 13 posts 73 karma points
    Oct 10, 2016 @ 10:35
    Tahir
    0

    I think it is occuring only because of

    // Layout
    @inherits WebViewPage<ViewModels.IDocumentViewModel<ISiteBase, IViewModelBase>>
    
    // View for the page
    @model ViewModels.RegisterViewModel
    

    If I do something

    @inherits UmbracoTemplatePage< MembershipRegisteration>
    

    It appears to be working fine.

    Now the question is for views to work properly after post back (remember the page renders fine on GET request), do we have to either inherit them from UmbracoTemplatePage or UmbracoViewPage and we can't use MVC WebViewPage?

  • Shannon Deminick 1524 posts 5270 karma points MVP 2x
    Oct 10, 2016 @ 11:01
    Shannon Deminick
    0

    For Umbraco pages you should use the Umbraco page types. Here's the page type hierarchy:

    • UmbracoTemplatePage<TContent> inherits from UmbracoViewPage<RenderModel<TContent>>
      • Allows use of dynamic models via CurrentPage ... not recommended to use this though, you should use strongly typed models.
    • UmbracoTemplatePage inherits from UmbracoViewPage<RenderModel>
      • Allows use of dynamic models via CurrentPage ... not recommended to use this though, you should use strongly typed models.
    • UmbracoViewPage inherits from UmbracoViewPage<TModel>
    • UmbracoViewPage<TModel> inherits from MVC WebViewPage<TModel>

    I am still unsure why you are getting that exception when using MVC WebViewPage, in theory you should be able to use that for sure. I have a feeling it's something to do with the ModelState that gets copied but I'd need to debug to replicate.

    Since you know how to replicate this issue, are you able to create an issue for it on the tracker with the simplest steps to replicate?

  • Tahir 13 posts 73 karma points
    Oct 10, 2016 @ 11:27
    Tahir
    1

    Thanks for replying.

    So, now I have update from 7.5.2 to 7.5.3 and still have the same issue.

    I am in a process of creating a blank website using nuget and will create the issue with steps to reproduce and upload the code (if allowed?) in next couple of minutes...

    Thanks

  • Tahir 13 posts 73 karma points
    Oct 10, 2016 @ 12:55
    Tahir
    100

    Ok, After a lot of debugging, I managed to find out why I was getting the error.

    It was not a Umbraco erro/bug but a mistake at my end.

    So effectively, What I was doing was, Under views, I was creating a separate folder for each document type. For this document type. I created the separate folder and created the view under that folder (BUT FAILED to delete the respective view under the VIEWS folder). On GET request, the view in the folder was called fine and I was seeing my changes.

    However, for surface controller, after postback, the view in the VIEWS folder gets called, hence the exception.

    Thank you very much for your help. :-)

  • Shannon Deminick 1524 posts 5270 karma points MVP 2x
    Oct 11, 2016 @ 07:38
    Shannon Deminick
    0

    Great, glad you found the problem! Also glad that everything eventually works as expected :)

    Not exactly sure why the View selected would change based on the surface controller postback or GET but might just be something odd with how View engines work with discovering views.

Please Sign in or register to post replies

Write your reply to:

Draft