Copied to clipboard

Flag this post as spam?

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


  • Madison James 31 posts 147 karma points
    Sep 25, 2018 @ 09:21
    Madison James
    0

    Cannot bind source content type ModelsBuilder.APIMode.Models.Home to model type ModelsBuilder.APIMode.Models.MyBlogPost.

    I'm using the ModelsBuilder.API.

    I have a Home Page, 
    @inherits UmbracoViewPage<Home>
    
    @using ModelsBuilder.APIMode.Models
    
    @using Newtonsoft.Json.Linq
    @using Umbraco.Web.Models
    @using ImageProcessor.Web
    
    @{
        Layout = "Master.cshtml";
    }
    

    calling a partial view,

    @{ Html.RenderPartial("Partials/Content/_LatestPost"); }
    

    _LatestPost

     @inherits UmbracoViewPage<MyBlogPost>
    
        @using ModelsBuilder.APIMode.Models
    
        @using Umbraco.Web.Models
        @using System.Collections.Generic;
        @using ImageProcessor.Web
    
        {
    

    With various code related to the MyBlogPost Model

    IPublishedContent npost = Model.Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
    

    for example

    And I'm getting the error you see in the Question title

    If anyone has any ideas I'm all ears

  • Nik 1591 posts 7148 karma points MVP 6x c-trib
    Sep 25, 2018 @ 09:32
    Nik
    1

    Hi Madison,

    Okay, so the issue you've got happening is you are calling a partial that is expecting a single blog post model. When you are calling this partial you aren't passing any model at all and as I understand it you are calling this from your home page template.

    Umbraco is trying to be helpful and is passing in your home page model to your partial, hence the error you are getting.

    Now, I'm going to make a few assumptions but I'm assuming your Blog Posts are children under your home node so what you could do is this:

    In your home template where you are calling the partial change it to this:

    @{
         IPublishedContent latestBlogPost = Model.Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
    
        @Html.Partial("/Content/_LatestPost", latestBlogPost)
    
    }
    

    This would then pass the latest blog post into your partial for rendering. However, it is not the most ideal option as before you call your partial you have to find the latest blog post reducing the ease of re-usability a bit. This should get you working though :-)

    Nik

  • Madison James 31 posts 147 karma points
    Sep 25, 2018 @ 09:44
    Madison James
    0

    Thank you, that will work, but I'm curious; is there a way to pass the complete model without breaking out the latest post?

    That would allow for greater re-usability.

    I really appreciate your help I hadn't seen this way of calling the partials in my searching,

    I have a lot to learn

    Madison

  • Nik 1591 posts 7148 karma points MVP 6x c-trib
    Sep 25, 2018 @ 09:54
    Nik
    1

    You have a few different ways of doing this in my opinion. Personally, I would put in a controller at this point and have a LatestPost (or LatestPosts) action that retrieves the latest post (or posts) and returns a view for displaying them.

    If you wanted to do it all in the view, you end up with a bit of messy behaviour.

    So you could change your LatestPost view to look like this:

    @inherits UmbracoViewPage<IPublishedContent>
    
    @using ModelsBuilder.APIMode.Models
    
    @using Umbraco.Web.Models
    @using System.Collections.Generic;
    @using ImageProcessor.Web
    
    {
         //assuming your home node is your root node
         var rootNode = Model.Content.Site();
         var latestBlogPost = rootNode.Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
    
         <div>@latestBlogPost.Name</div>
    }
    

    This would make it reusable.

  • Madison James 31 posts 147 karma points
    Sep 25, 2018 @ 10:02
    Madison James
    0

    OK, So this is what I currently have

    @inherits UmbracoViewPage<MyBlogPost>
    
    @using ModelsBuilder.APIMode.Models
    
    @using Umbraco.Web.Models
    @using System.Collections.Generic;
    @using ImageProcessor.Web
    
    @{
    
        IPublishedContent npost = Model.Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
        int cid = npost.Id;
    
        string imageUrl = npost.HasValue("MainImage") ? npost.GetPropertyValue<IPublishedContent>("MainImage").Url : string.Empty;
        string adate = npost.GetPropertyValue<DateTime>("articleDate").ToString("dddd, MMM dd, yyyy");
    
        string title = npost.HasValue("title") ? npost.GetPropertyValue<string>("title") : npost.Name;
        string extLink = npost.HasValue("externalURL") ? npost.GetPropertyValue<string>("externalURL") : string.Empty;
        bool extYes = extLink != "";
        string auth = npost.HasValue("authorName") ? npost.GetPropertyValue<string>("authorName") : npost.Name;
        string uDate = npost.HasValue("articleUpdated") ? npost.GetPropertyValue<DateTime>("articleUpdated").ToString("dddd, MMMM dd, yyyy") : string.Empty;
    
        IEnumerable<TagModel> cTags = Umbraco.TagQuery.GetTagsForEntity(cid, "Categories");
        IEnumerable<TagModel> pTags = Umbraco.TagQuery.GetTagsForEntity(cid, "posts");
    
    
    }
    

    Is the example you gave your suggestion for using a controller?

    Thanks again for your help Nik,

    Madison

  • Madison James 31 posts 147 karma points
    Sep 25, 2018 @ 10:04
    Madison James
    0

    And this is without making your suggested change to the Home page calling this partial

  • Nik 1591 posts 7148 karma points MVP 6x c-trib
    Sep 25, 2018 @ 10:13
    Nik
    0

    Hi Madison,

    I got an e-mail saying you've replied but I can't see your response.

    I think I saw it before it disappeared so this may or may not apply correctly to what you asked, but yes you could use this partial view update instead of the initial changes I mentioned :-)

    Nik

  • Madison James 31 posts 147 karma points
    Sep 25, 2018 @ 10:18
    Madison James
    0

    Yes it was wierd, I sent two replies and then hit refresh a few minutes later and my replies were gone.

    Here is what I said,

    This is what I have currently, before making any changes you suggested.

    @inherits UmbracoViewPage<MyBlogPost>
    
    @using ModelsBuilder.APIMode.Models
    
    @using Umbraco.Web.Models
    @using System.Collections.Generic;
    @using ImageProcessor.Web
    
    @{
    
        IPublishedContent npost = Model.Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
        int cid = npost.Id;
    
        string imageUrl = npost.HasValue("MainImage") ? npost.GetPropertyValue<IPublishedContent>("MainImage").Url : string.Empty;
        string adate = npost.GetPropertyValue<DateTime>("articleDate").ToString("dddd, MMM dd, yyyy");
    
        string title = npost.HasValue("title") ? npost.GetPropertyValue<string>("title") : npost.Name;
        string extLink = npost.HasValue("externalURL") ? npost.GetPropertyValue<string>("externalURL") : string.Empty;
        bool extYes = extLink != "";
        string auth = npost.HasValue("authorName") ? npost.GetPropertyValue<string>("authorName") : npost.Name;
        string uDate = npost.HasValue("articleUpdated") ? npost.GetPropertyValue<DateTime>("articleUpdated").ToString("dddd, MMMM dd, yyyy") : string.Empty;
    
        IEnumerable<TagModel> cTags = Umbraco.TagQuery.GetTagsForEntity(cid, "Categories");
        IEnumerable<TagModel> pTags = Umbraco.TagQuery.GetTagsForEntity(cid, "posts");
    
    
    }
    

    My question was, Is this your suggestion for using a controller.

    Thanks for your help, Madison

  • Nik 1591 posts 7148 karma points MVP 6x c-trib
    Sep 25, 2018 @ 11:16
    Nik
    0

    Hi Madison

    Okay, so this is your original view:

    @inherits UmbracoViewPage<MyBlogPost>
    
    @using ModelsBuilder.APIMode.Models
    
    @using Umbraco.Web.Models
    @using System.Collections.Generic;
    @using ImageProcessor.Web
    
    @{
    
        IPublishedContent npost = Model.Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
        int cid = npost.Id;
    
        string imageUrl = npost.HasValue("MainImage") ? npost.GetPropertyValue<IPublishedContent>("MainImage").Url : string.Empty;
        string adate = npost.GetPropertyValue<DateTime>("articleDate").ToString("dddd, MMM dd, yyyy");
    
        string title = npost.HasValue("title") ? npost.GetPropertyValue<string>("title") : npost.Name;
        string extLink = npost.HasValue("externalURL") ? npost.GetPropertyValue<string>("externalURL") : string.Empty;
        bool extYes = extLink != "";
        string auth = npost.HasValue("authorName") ? npost.GetPropertyValue<string>("authorName") : npost.Name;
        string uDate = npost.HasValue("articleUpdated") ? npost.GetPropertyValue<DateTime>("articleUpdated").ToString("dddd, MMMM dd, yyyy") : string.Empty;
    
        IEnumerable<TagModel> cTags = Umbraco.TagQuery.GetTagsForEntity(cid, "Categories");
        IEnumerable<TagModel> pTags = Umbraco.TagQuery.GetTagsForEntity(cid, "posts");
    
    }
    

    If you change this line:

    @inherits UmbracoViewPage<MyBlogPost>
    

    To:

    @inherits UmbracoViewPage<IPublishedContent>
    

    And this line:

    IPublishedContent npost = Model.Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
    

    to:

    IPublishedContent npost = Model.Site().Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
    

    That should make the View work where ever you want to use it. However if you wanted to go down the Controller approach there would be more changes that would be needed. The Controller approach changes quite a bit of the behaviour so I've not gone down this route here for you but kept it all in the view.

    Does that make sense?

    If you want me to try and explain the Controller approach I can but not right now. I should be able to draw that up later on today for you.

    Thanks

    Nik

  • Madison James 31 posts 147 karma points
    Sep 25, 2018 @ 12:36
    Madison James
    0

    Thanks again for your time Nik, But this only errors differently. I've tried it with your partial code in the home template and my original renderpartial and the result is the same.

    Object reference not set to an instance of an object.

    Line 11:     IPublishedContent npost = Model.Site().Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "myBlogPost").OrderByDescending(x => x.GetPropertyValue<DateTime>("articleDate")).FirstOrDefault<IPublishedContent>();
    Line 12:     int cid = npost.Id;
    

    The error is line 12

    It's been a long night and I'm done, I'm in Texas, so I'll talk to you later.

    Thanks, Madison

  • Madison James 31 posts 147 karma points
    Sep 26, 2018 @ 01:20
    Madison James
    0

    Hi Nik, Not sure what part of the world you're in but I hope you had a great day or night after helping me.

    I would eventually like to solve this but I put all of my working code back in place on my dev server, which is where I've been applying, what you've been helping me with.

    According to the Umbraco docs, https://our.umbraco.com/documentation/Reference/Templating/Mvc/partial-views Under Strongly typed Partial Views

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<MyModel>
    

    should work, which is exactly what I'm trying to do.

    You mentioned earlier that Umbraco was "helping" when I call the partial. Can you tell me why that is happening if the docs tell me to do the above.

    It's been a few years, and prior to using Umbraco starting with 7.0.4, since I needed to create controllers but if that is necessary I can do that.

    This problem actually arose out of the need to use,

    @Html.GetGridHtml(Umbraco.AssignedContentItem, "contentGrid", "CSUSKGrid")
    

    for example, instead of

    @Html.Raw(@description)
    

    On the _latestpost partial you were helping with I went to change an editor from rich text to grid for a property named excerpt. I can't figure out how to get access to excerpt in a way that can be used with GetGridHtml without using the model.

    I hope the way I've worded this makes sense. Thanks again

  • Nik 1591 posts 7148 karma points MVP 6x c-trib
    Sep 27, 2018 @ 08:21
    Nik
    100

    Hi Madison,

    Sorry I didn't see your reply yesterday

    Yes, the docs are correct, but the way you are calling your partial you aren't passing it in a model.

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<MyModel> is telling the partial view that it is expecting a Model of type MyModel. But it doesn't automatically know what actual instance of the model to use.

    So when you call your partial like this @Html.Partial("MyPartial") you are ommiting passing the model. As a result Umbraco uses the Model from the calling request and tries to pass that to your partial.

    What you should be doing is @Html.Partial("MyPartial", new MyModel()), or more realistically you'd be getting your instance of MyModel from some other bit of logic.

    Okay, so your original problem you reported is caused by the above reasoning. So to resolve it your need to pass in the correct model. But as I flagged the quickest resolution isn't ideal as it's not a nice reusable unit.

    Following on from that I suggested a way in which you could wrap it all in a view, but it was based on an assumption on your site structure.

    I assumed, as I mentioned, that you site structure was something along the lines of this:

      > Home
         > MyBlogPost1
         > MyBlogPost2
         > MyBlogPost3
         > SomeOtherPageThatIsn'tABlog
    

    The assumption here was made based on your original line of code here:

    IPublishedContent npost = Model.Children.Where(x => x.IsVisible() 
         && x.DocumentTypeAlias == "myBlogPost").
         OrderByDescending(x => 
          x.GetPropertyValue<DateTime>("articleDate"))
           .FirstOrDefault<IPublishedContent>();
    

    If this is not your structure it will explain why you are getting the Object Reference Not Set exception you mentioned laterly.

    I'm avoiding explaining the controller approach because it would add a level of complexity to your build and at this stage it would be better to just get you up and running first.

    Finally, in your look to call the grid, when it comes down to actually getting the grid data you probably won't be using Umbraco.AssignedContentItem I suspect, instead you are probably going to be wanting to use the instance of your blog post. But we can come back to that side of things.

  • Madison James 31 posts 147 karma points
    Sep 28, 2018 @ 03:30
    Madison James
    0

    Hi Nik, I had to leave everything on the production server running my prior code because I had to get another project underway and my stuff always waits.

    I'm going to try your suggestion again next week and once I get it working I may ask you something else but you've been great.

    I realized after you said something about assumption that your assumption appears to have been my fault. I had several views open at the same time and I either posted the partial code that went with the blog landing page or hadn't finished editing the latestpost view before posting the code here, can't be sure because I had to back the changes out of the dev box to stay in sync with production.

    Thanks again, Madison

Please Sign in or register to post replies

Write your reply to:

Draft