Copied to clipboard

Flag this post as spam?

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


  • Chris Smith 4 posts 51 karma points
    Feb 17, 2014 @ 11:26
    Chris Smith
    0

    Custom MVC routing with custom RenderModel and HttpPost

    Hi,

    I have followed the guide by Shazwazza for custom MVC Routing
    http://shazwazza.com/post/Custom-MVC-routing-in-Umbraco

    So I now have a Controller that inherits UmbracoController and a custom model that inherits RenderModel.
    I render the view on HttpGet and the page loads correctly

    If I have a form on the page which posts back to the same controller method but on httppost then I get an error as the Render Model cannot be created.

    On the initial get I retrieve the page by using the following code

    [HttpGet]
    public ActionResult Index()
    {
    Int32
     nodeID = umbraco.uQuery.GetNodeIdByUrl("/register"); IPublishedContent content = this.Umbraco.TypedContent(nodeID); RegisterRenderModel model = new RegisterRenderModel(content); RouteData.DataTokens["umbraco"] = model;
    return View("Index", model); }

     

    Then on the post the error is caused by
    UmbracoContext.Current.PublishedContentRequest = null or UmbracoContext.Current.PageId = null
    It cannot create an instance of the custom RenderModel so throws the error. Never gets to the post method.

    [HttpPost]
    public ActionResult Index(RegisterRenderModel model)
    {
    // do something here
    }

    How can I do a httpost back with the custom MVC routing and custom model?
    I did think to post jsut the form data to another action method but then I needed to reload the page due to some server side validation failed. Therefore need a standard form postback

    Thanks

  • Chris Smith 4 posts 51 karma points
    Feb 17, 2014 @ 11:27
    Chris Smith
    0

    Just though I should add code for the model

    public class RegisterRenderModel : RenderModel
        {
    
            public RegisterRenderModel()
                //: this(new UmbracoHelper(UmbracoContext.Current).TypedContent(UmbracoContext.Current.PageId)) 
                : this(UmbracoContext.Current.PublishedContentRequest.PublishedContent)
            {
            }
    
            public RegisterRenderModel(IPublishedContent content)
                : base(content, CultureInfo.CurrentUICulture) 
            {
    
            }
        }
  • Chris Smith 4 posts 51 karma points
    Sep 04, 2014 @ 00:05
    Chris Smith
    0

    In the end I reverted back to RenderMvcController

    Then the Post went to a SurfaceController method

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Sep 04, 2014 @ 12:15
    Jeroen Breuer
    0

    Hello,

    If you want to use a custom controller have a look at the IRenderMvcController interface. If you inherit from that it works the same as RenderMvcController. I'm using my SurfaceController with that interface so I can route hijack and post to the same controller.

    Jeroen

  • Danny Blatant 91 posts 358 karma points
    Oct 09, 2014 @ 14:00
    Danny Blatant
    0

    I have experianced a similar problem to the OP. I have also follewed the guide quoted by th OP, but moreso I am following this guide from umbracp.com : https://umbraco.com/follow-us/blog-archive/2014/1/27/a-practical-example-of-route-hijacking-in-umbraco.aspx

    I realise that Route Hijacking is not the same as Partial Macro Views (PMV), however the reason I am trying to impliment RenderModel in my PMV is so the View can get to the Umbraco and Model.Content objects. The RenderModel solution seems to be the right way to go, but I've hit a snag in the Umbraco Content Editor...

    I have created a Partial Macro View, with the intent of embedding in RTE's where required. Here's my structure

    Models - BrandSelectorViewModel.cs ( BrandSelectorViewModel : RenderModel ) Controllers - BrandSelectorSurfaceController.cs ( BrandSelectorSurfaceController : SurfaceController ) Views - Partials - _brandSelector.cshtml ( @model EnergieUmbrella2.Models.BrandSelectorViewModel ) - MarcoPartials - brandSelector.cshtml ( @inherits Umbraco.Web.Macros.PartialViewMacroPage )

    The MacroPartial template simple calls Action of Index on BrandSelectorSurface.

    The BrandSelectorSurfaceController has one ActionResult (Index) which returns a PartialView(_brandSelector,BrandSelectorViewModel()). This seems to work fine!

    Now the BrandSelectorViewModel works just fine when viewing the page, it creates the inherited RenderModel and I can access Model.Content from my view. However when I try to save the DocType in the Umbraco backend, whic hhas an RTE with my PVM embedded, it throws an error in the BrandSelectorViewModel Instanciation.

    Like the Op, it seems that in the Admin pages UmbracoContext.Current.PublishedContentRequest is null, so I can't get the PublishedContent. An error is thrown when I try to edit the page:

    An exception of type 'System.NullReferenceException' occurred in MySite2.dll but was not handled in user code

    Additional information: Object reference not set to an instance of an object.

    Can anyone advise on this? I'm open to the answer of "Don't inherit from RenderModel in custom ViewModels" but if thats the answer how can I get the view to present me with the Umbraco helper and the Model.Content object? As I understand it in the PartialView I can not use @model EnergieUmbrella2.Models.BrandSelectorViewModel and @inherits Umbraco.Web.Macros.PartialViewMacroPage as the latter supplies a different RenderModel derivative...

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Oct 09, 2014 @ 14:05
    Jeroen Breuer
    0

    If you want a fully working example for Umbraco 7 have a look at the Hybrid Framework.

    Jeroen

  • Danny Blatant 91 posts 358 karma points
    Oct 09, 2014 @ 15:02
    Danny Blatant
    0

    Hello again Jeroen!

    Ok I will check out the full Hybrid project again, indeed I used it to solve my nuPickers issues before (I beleive we first met in that topic). However I do note that the project on GitHub seems to be devoiud of controllers and models! I'm usre it's not missing them however there are no distinct folders for them!!

    I'm off to watch the video, but in the meantime if anyone can make a consise suggestion that might accelorate my understanding that would be most useful!

    Thanks for the link Jeroen!

  • Danny Blatant 91 posts 358 karma points
    Oct 09, 2014 @ 16:52
    Danny Blatant
    0

    Hi Jeroen,

    I'm looking through hybrid, and have watched the entire uHangout video, but I am struggling to see how this answers my sepecific question.

    I fear I have left some important information out. Firstly my Model is not derived from any IPublishedContent, in fact my models are pulling data from a 3rd party source, so I am not sure how the Model Builder can deal with this!

    Also, I am working on a site that has had a fair bit of development done already. I am not keen to roll back and start again in the Hybrid framework. Of course I will try my best to use the framework to pick and choose the best practice pieces that can help.

    Finally, My model is a model for a Partial View Macro, not a content page (IPublishedContent), therefor I'm thinking that all the IPUblishedContent derived content is not applicable...

    I am sure however that you can help me find my amswer! I'm still trying to work out if the 'MasterModel' can help me out here, or at least give me some clues as to how the existing models and views to work!

    Could you possibly spare a moment to help me work through my specific issue?

    To Recap, I have a Partial Macro View, which calls an action on a SurfaceController that in turn returns a Partial View with my View Model. This View Model is inheriting from RenderModel so that the Model in the view works and has access to the Context object.

    The issue is the RenderModel dependancy requires the IPublishedContent to be passed in, which is fine when we view via the frontend, as the Current Page is used (UmbracoContext.Current.PublishedContentRequest.PublishedContent). Howeve when the PartialView is rendered within the RTE UmbracoContext.Current.PublishedContentRequest is null, so it throws an exception on the constructor.

    Here is my emptied Model:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    using Umbraco;
    using Umbraco.Web;
    using Umbraco.Web.Models;
    using Umbraco.Core;
    using Umbraco.Core.Models;
    
    namespace MySite2.Models
    {
        public class BrandSelectorViewModel : RenderModel
        {
            public BrandSelectorViewModel() : base(UmbracoContext.Current.PublishedContentRequest.PublishedContent)
            {
                //constructor
    
            }
            public string test() { return "Hello Custom Model"; }
        }
    }
    

    i am sure I'm just missing a small bit of fundimental understanding here. Either my implimentation of the base method in the constructor, or perhaps the way I'm implimenting my Model in the View... Anyway, here's the view :

    Firstly, this one works in the frontend, but fails in the Model constructor when rendered in the RTE.

    @model EnergieUmbrella2.Models.BrandSelectorViewModel
            <div id="brands" class="selfClear">
                <a href="@(Model.Content.NiceUrl() + "?brand=" + brand.UrlName)" title="Test Link" />
                <p>@Model.test()</p>
            </div>
    

    Now, this view works in the RTE and The front end, however my custom Model method test() is not available, the same effect is seen if I remove the RenderModel inheritance on the model, as my custom Model is not pulled in anyway...

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
            <div id="brands" class="selfClear">
                <a href="@(Model.Content.NiceUrl() + "?brand=" + brand.UrlName)" title="Test Link" />
                <p>@Model.test()</p>
            </div>
    

    I would hazzard a guess that the later view is correct, as that is how it's described on umbraco.tv and in the U7 documentation. So the question might be more simple = "How can I extend the RenderModel Passed to my Partial View?".

    Please can anyone help me? Jeroen thank you for your advise so far (I don't mean to turn it away but I don't beleive Hybrid provides the answer that I can understand) however if you can help me reach understanding I will send you some virtual beer tokens!!!

Please Sign in or register to post replies

Write your reply to:

Draft