Copied to clipboard

Flag this post as spam?

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


  • Paul Griffiths 370 posts 1021 karma points
    Jan 04, 2019 @ 09:48
    Paul Griffiths
    0

    Partial Views | Cannot bind source type to model type Umbraco.Web.Models.RenderModel.

    Hi All,

    I have the following controller: ServicesLandingPageController which is named the same as my document type which results in the request hitting my Index action method (which takes a parameter of RenderModel) which after doing a bunch of processing returns a custom model called ServicesLandingPageViewModel. Here is a snippet

                var vm = new ServicesLandingPageViewModel(model.Content)
            {
                Heading = model.Content.GetPropertyValue<string>("heading"),
                MainContent = model.Content.GetPropertyValue<IHtmlString>("mainContent"),
                ServicesByCategory = new List<ServicesByCategory>()
            };
    
    return CurrentTemplate(vm); 
    

    After building up my ViewModel and passing it to my ServicesLandingPage.cshtml view which is strongly typed.

    @inherits UmbracoViewPage<MyProject.Models.ServicesLandingPageViewModel>
    

    Inside my view, I can call my view model properties as expected however, I have a partial (to load a breadcrumb trail) that inherits UmbracoTemplatePage. e.g.

    @inherits UmbracoTemplatePage
    
    @{
        var selection = Model.Content.Ancestors().ToList();
    }
    
    <div class="breadcrumb-column col-md-6 col-sm-4 col-xs-12">
        <ul class="bread-crumb clearfix">
     ......
    

    This results in the following binding error which makes sense because im dealing with two different types

    enter image description here

    In the past for partials that are bound to a model type that i have created i have passed in an empty model like so which works.

    @{ Html.RenderPartial("Shared/_ContactForm", new ContactFormViewModel() {initialise properties if needed });} 
    

    I am unable to pass in RenderModel e.g.

    @{Html.RenderPartial("Layout/_PageBanner", new RenderModel());}
    

    I think i can create an an @Html.Action call into a controller method that builds up a breadcrumb view model and pass that but my main question here (mainly for understanding as im learning this approach) is whether it is possible to call a partial that inherits UmbracoTemplatePage into a strongly typed view?

    Apologies if i have missed something obvious :|

    Thank you

    Paul

  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Jan 04, 2019 @ 10:30
    Dan Diplo
    0

    Have you read the docs on passing a model to a strongly-typed partial?

    https://our.umbraco.com/Documentation/Reference/Templating/Mvc/partial-views#strongly-typed-partial-views

    You would do something like:

    @Html.Partial("Layout/_PageBanner", yourModelInstance)
    

    This would pass an instance of YourModel to the partial. In your partial you would then use:

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<YourModel>
    
  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Jan 04, 2019 @ 10:49
    Nik
    100

    Hi Paul,

    Okay, so from my point of view I'd change your partial inherit from UmbracoViewPage instead of UmbracoTemplatePage.

    In general UmbracoTemplatePage shouldn't really be used any more, you are better off with UmbracoViewPage.

    UmbracoViewPage, by default, looks for IPublishedContent to be passed to it I believe, instead of RenderModel.

    Then, if your custom model stores a copy of the IPublishedContent in it, you can pass the IPublishedContent to your partial.

    As I understand it, originally UmbracoTemplatePage was designed for your page template files, and UmbracoViewPage was designed for use in partial views. However UmbracoTemplatePage is only needed these days for sites that are using Dynamics (please avoid this :-) ) so instead you should just use UmbracoViewPage for Partials and Page Templates alike.

    Does that help?

    Nik

  • Paul Griffiths 370 posts 1021 karma points
    Jan 04, 2019 @ 10:59
    Paul Griffiths
    0

    Hi Dan, Nik

    Thank you for your responses. @Dan, i think you miss-understood my question. Yes, i have read the information on the link that you provided but it still didn't clear things up for me.

    As indicated by the contact example in my original post, I understand that i can pass a copy of my model to the partial but this means that the breadcrumb partial needs to be of a specific type. As the breadcrumb is used on a variety of differently typed pages, changing the partial to be @inherits Umbraco.Web.Mvc.UmbracoViewPage <YourModel> wouldn't work(?) for what i want (hope that makes sense). I believed that i could work around this by using @HTML.action and building up a breadcrumb view model and using that in my views.

    I am trying to understand the best way to call a partial that is not strongly typed on a view that is strongly typed.

    @Nik thanks for the information re: UmbracoTemplatePage vs UmbracoViewPage, this is really helpful! If i understand your response, if i am to pass IPublishedContent with my ServicesLandingPageViewModel (built in my controller) then i am in a position to pass that to the partial?

    Thanks again both for your responses.

    Paul

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Jan 04, 2019 @ 11:08
    Nik
    0

    Hi Paul,

    Yes.. so I'm going to make an assumption.. but you are creating an instance of ServicesLandingPageViewModel and passing in model.Content.

    model.Content, is I believe, looking at your code, an instance of IPublishedContent. If you expose this on your model you can then pass it through to your partial.

    so if your ServicesLandingPageViewModel was a bit like this:

    public class ServicesLandingPageViewModel
    {
    
         public ServicesLandingPageViewModel(IPublishedContent rawContent){
              RawContent = rawContent;
         }
         public IPublishedContent RawContent {get; private set;}
    
         /* .... all your existing properties ... */
    }
    

    (I had to assume names and your current behaviour in your existing model)

    Then in your view you can do this:

      @Html.Partial("layout/_PageBanner", Model.RawContent)
    

    This would then pass your IPublishedContent for the current page through to the partial view.

    Nik

  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Jan 04, 2019 @ 11:12
    Dan Diplo
    0

    Yes, like Nik says, any model you have should implement IPublishedContent so you can pass any model to a partial that way.

    You can then use:

    Umbraco.Web.Mvc.UmbracoViewPage <IPublishedContent>
    

    or just leave it as UmbracoTemplatePage which expects IPublishedContent.

  • Paul Griffiths 370 posts 1021 karma points
    Jan 04, 2019 @ 11:20
    Paul Griffiths
    1

    Hi both,

    This makes sense :). I will have a go implementing later today and feedback the results.

    Thank you very much for your responses.

    Paul

  • Paul Griffiths 370 posts 1021 karma points
    Jan 04, 2019 @ 19:09
    Paul Griffiths
    1

    Hi,

    Just had an opportunity to try the solution and it worked a treat!

    I already had a constructor so just needed to add the RawContent property and assign that to the IPublishedContent being passed in.

    enter image description here

    In my view i had that following

    @inherits UmbracoViewPage<ElectricsPlumbing.Models.ServicesLandingPageViewModel>
    
    @{
        Layout = "Layout.cshtml";
    }
    
    @{Html.RenderPartial("Layout/_PageBanner", Model.RawContent);}
    

    which called into my breadcrumb partial as so

    enter image description here

    Thank you for your help

Please Sign in or register to post replies

Write your reply to:

Draft