Copied to clipboard

Flag this post as spam?

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


  • Justin 19 posts 163 karma points
    Apr 17, 2015 @ 05:31
    Justin
    2

    My Solution to passing Models to Strongly Typed Umbraco Views

    Hi all,

    i am quite new to umbraco and hit an issue when trying to integrate an existing web app into the Umbraco framework.

    The problem related to my original controllers (which i modified to derive from RenderMvcController) passing ViewModels to Strongly typed Umbraco Views.

    After some investigation i learned that if i wanted my Views to have access to the Umbraco helper and Page Properties then my ViewModels need to derive from RenderModel.

    I also found that if my my Controller returned IEnumerable then i have to do something like this (from post https://our.umbraco.org/forum/developers/razor/55389-UmbracoTemplatePage-and-strongly-typed-view-not-working-together?p=1):

    public class myViewModel: RenderModel {
    public myViewModel() : this(new UmbracoHelper(UmbracoContext.Current).TypedContent(UmbracoContext.Current.PageId)) { }
    
    public myViewModel(IPublishedContent content, CultureInfo culture) : base(content, culture) { }
    public myViewModel(IPublishedContent content) : base(content) { }
    //the other properties you need to pass to the view
    

    }

    The above 2 things i learned were problematic for me for the following reasons:

    1. Although the application i am integrating into umbraco has only a few ViewModels i was hoping, if everything went well, to do the same for another application i have, which is much larger, so modifying the ViewModels would be a headache.

    2. Adding RenderModel to my ViewModels project would mean a Dependency on Umbraco. This wasn't possible as the ViewModels project is part of a larger SDK which other users will use to Create front-ends for my Application.

    3. My ViewModels are POCO and are mapped to my domain models using Automapper. Adding RenderModel to the ViewModels caused Automapper to fail as the domain models didn't have the associated RenderModel Members 'Content' and "CurrentCulture'. Again, modifying my Automapper config would be a headache in a large application.

    I briefly had a look at UmbracoMapper (can be found on our umbraco) which maps umbraco content types to POCO models. Making umbraco Content Strongly Typed in the View. The argument they give for this is that Umbraco doesn't follow true MVC patterns as a lot of the logic for retrieving page content and the likes is in the View. Altough i agree with that statement, i don't see UmbracoMapper as a solution as it then binds Umbraco content to our POCO Models meaning that if a property is added to an umbraco document type it then needs to be added to the Model (kind of defeats the object in my opinion).

    I wanted something that was kind of in the middle. To leave things as they are for umbraco content but to be able to return POCO models to my Views making my Views Strongly Typed.

    The solution, for me, turned out to be a very simple one.

    Create a new Project and add references to umbraco and Umbraco.Core. Create a new Class called umbracoViewModel with the following code:

        public class umbracoViewModel<T> : RenderModel
        {
            public umbracoViewModel(): 
                base(UmbracoContext.Current.PublishedContentRequest.PublishedContent)
            {
            }
            public T customModel { get; set; }
        }
    

    We are simply creating a Generic class that derives from RenderModel with a Generic property called customModel.

    So, in your controller you can generate your Model in the following way:

    //Create our umbraco friendly Model

    umbracoViewModel<myPOCOViewModel> uView = new umbracoViewModel<myPOCOViewModel>();
    

    //Create our POCO ViewModel

    myPOCOViewModel myView = new myPocoViewModel(){
      //set some values
    }
    

    //set the Generic T property of our uView to our POCO view.

    uView.customModel = myView;
    

    Note: The example above uses a custom class myPOCOViewModel as an example but the Generic umbracoViewModel can obviously accept any Type. So you could do

    umbracoViewModel<IEnumerable<int>> uView = new umbracoViewModel<IEnuerable<int>>();
    IEnumerable<int> myInts = new List<int>();
    //..populate myints
    uView.customModel = myInts;
    

    then in your view you have:

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<myNamespace.umbracoViewModel<myModels.myPOCOViewModel>>>
    var umbracoContent = Model.Content;
    var myModel = Model.customModel;
    

    This means i can develop a front-end for my Application in Umbraco from my existing code by modifying only the Controllers and Views (front-end, makes sense) but leaving The rest of my code base as is.

    Just thought i would share with the community in case it helps somebody out as i saw quite a few solutions to this but none that quite fitted my problem.

    cheers

  • Alex Skrypnyk 6131 posts 23950 karma points MVP 7x admin c-trib
    Apr 17, 2015 @ 10:32
    Alex Skrypnyk
    0

    Great approach Justin!

    Thanks

  • John Churchley 272 posts 1258 karma points c-trib
    Apr 17, 2015 @ 10:40
    John Churchley
    0

    Really useful, thanks for sharing Justin!

Please Sign in or register to post replies

Write your reply to:

Draft