Copied to clipboard

Flag this post as spam?

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


  • Charles Goodman 2 posts 82 karma points
    Oct 09, 2020 @ 15:39
    Charles Goodman
    0

    Rendering custom SQL table data into a model

    Hi there!

    I'm trying to render some data that I'm fetching from a custom SQL table into a specific model (in this case, the 'People' model that comes with the default Umbraco installation, located over localhost:PORT/people), but to no avail.

    I've implemented both a controller and a model, followed by a partial view that fetches the variables from those two. However, when trying to render them in said page, by using...

    @Html.Partial("~/Views/Partials/UserInfo.cshtml")
    

    ...it returns the following error:

    The model item passed into the dictionary is of type 'Umbraco.Web.PublishedModels.People', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[SimpleTest.Models.TestUsers]'.
    

    As for the things I have implemented, this is the controller, in my App_Code folder:

    namespace SimpleTest.Controllers {
        public class TestUsersController : SurfaceController
            private readonly IScopeProvider _scopeProvider;
    
            public TestUsersController(IScopeProvider scopeProvider)
            {
                _scopeProvider = scopeProvider;
            }
    
            [ChildActionOnly]
            public IEnumerable<TestUsers> UserInfo()
            {
                using (var scope = _scopeProvider.CreateScope())
                {
                    var testusers = scope.Database.Fetch<TestUsers>("SELECT * FROM dbo.MyTestUsers");
                    return testusers;
                }
                return null;
            }
        }
    }
    

    As for the model,

    namespace SimpleTest.Models
    {
        [TableName("MyTestUsers")]
        public class TestUsers
        {
            [Column("ID")]
            [PrimaryKeyColumn]
            public int Id { get; set; }
    
            [Column("Name")]
            public string Name { get; set; }
    
            [Column("DOB")]
            public System.DateTime DateOfBirth { get; set; }
        }
    }
    

    Lastly, my partial view:

    @using SimpleTest;
    @using SimpleTest.Models;
    @model IEnumerable<TestUsers>
    
    @foreach (TestUsers item in Model)
    {
        <p>@item.Id</p>
        <p>@item.Name</p>
        <p>@item.DateOfBirth</p>
    }
    

    How can I circumvent this issue so that I can correctly render said content into the model in question?

    Much appreciated in advance!

    Charles

  • Marc Goodson 1451 posts 9716 karma points MVP 5x c-trib
    Oct 10, 2020 @ 09:18
    Marc Goodson
    100

    Hi Charles

    I'm missing the point where you are calling your Partial, but if it's inside another view, then that is why you are getting 'The model item passed into the dictionary ... error)...

    Essentially when you call Html.Partial, if you don't specify the Model you want to pass to the Partial, then the 'Current' Model of the view will be passed instead.

    so when you call

    @Html.Partial("~/Views/Partials/UserInfo.cshtml")
    

    It is the same as calling

    @Html.Partial("~/Views/Partials/UserInfo.cshtml", Model)
    

    and your 'Model' is of type: Umbraco.Web.PublishedModels.People

    There are many kinds of approaches for pulling in data from an external source to use in an Umbraco View, I think the closest to what you are trying to do here, is to have your SurfaceController return the Partial View,

    and in your page View, call the SurfaceController Action using

    @Html.Action("UserInfo","TestUsers")
    

    The Surface Controller would need to return an ActionResult

    and instead of returning the IEnumerable of TestUsers would return the partial:

    return Partial(~/Views/Partials/UserInfo.cshtml, testusers);
    

    Other ways of approaching this would be to use:

    RouteHijacking - https://our.umbraco.com/Documentation/Reference/Routing/custom-controllers - where you create a different type of controller that handles the request, and allows you to build a custom 'PeopleExtended' view model, based on the Umbraco PeopleModel - but with an additional property called UserInfo that you populate in the Index action of the controller

    or

    UmbracoApiController - https://our.umbraco.com/Documentation/Reference/Routing/WebApi/ create an endpoint that returns the list of users, and use client side code to call it when the page loads to populate the Users

    There are a few more too, but there's nothing wrong with your Surface Controller approach either!

    regards

    Marc

  • Charles Goodman 2 posts 82 karma points
    Oct 12, 2020 @ 11:51
    Charles Goodman
    0

    Hi Marc!

    Thank you so much for the speedy reply and for the insight. I've managed to make it work fully with SurfaceController - I'll be now looking into the other alternatives you've provided and attempt to reimplement this solution of mine with those approaches.

    Thanks yet again!

    Charles

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies