Simplest Way To Do Dynamic View Models in ASP.NET MVC 3

14,242

Like you said, it's not supported. (I'm not saying dynamic View Models aren't supported - I'm saying what you're trying to do is not)

You could probably neaten up the LINQ query, but in the end your best bet would be to simply create a custom View Model. Seriously, it will take you about 30 seconds to do that.

I know dynamic is new and cool and everything, but your code will be a lot neater and easier to maintain if you just stick with a custom View Model in this case.

I would only go with a dynamic View Model in the very simple scenarios - most of the time you probably want to stick with what we've been doing all along - custom View Models.

Share:
14,242
Derek Morrison
Author by

Derek Morrison

Web developer, lousy Russian student, ex-oboist, ex-Alabamian.

Updated on June 04, 2022

Comments

  • Derek Morrison
    Derek Morrison almost 2 years

    Caveat: This might be an inappropriate use of C#'s dynamic keyword and I probably should be using a strongly-typed view model, but...

    I'm trying to avoid creating a strongly-typed view model by passing a C# 4 dynamic type to my view. I have this in my controller:

        public ActionResult Index()
        {
            var query =
                from fr in db.ForecastRates
                join c in db.Codes
                on 
                    new { Code = fr.RateCode, CodeType = "ForecastRate" }
                equals 
                    new { Code = c.CodeValue, CodeType = c.CodeType }
                select new
                {
                    RateCode = fr.RateCode,
                    RateCodeName = c.CodeName,
                    Year = fr.Year,
                    Rate = fr.Rate,
                    Comment = fr.Comment
                };
    
            // Create a list of dynamic objects to form the view model
            // that has prettified rate code
            var forecastRates = new List<dynamic>();
    
            foreach (var fr in query)
            {
                dynamic f = new ExpandoObject();
    
                f.RateCode = fr.RateCode;
                f.RateCodeName = fr.RateCodeName;
                f.Year = fr.Year;
                f.Rate = fr.Rate;
                f.Comment = fr.Comment;
    
                forecastRates.Add(f);
            }
    
            return View(forecastRates);
        }
    

    ...and this in my view (I'm using MVC 3's Razor view engine):

            @inherits System.Web.Mvc.WebViewPage<IEnumerable<dynamic>>
    
            ...
    
            <tbody>
                @foreach (var item in Model) {
                <tr>
                    <td>@item.RateCodeName</td>
                    <td>@item.Year</td>                            
                    <td>@item.Rate</td>
                    <td>@item.Comment</td>
                </tr>
                }
            </tbody>
    

    I don't like how I iterate through the LINQ result to form the List of dynamic objects.

    I'd like to initialize each ExpandoObject inside the LINQ query, but that doesn't seem to be supported.

    I tried casting the the query result as List, but that didn't work because you can't convert anonymous type to dynamic.