Simplest Way To Do Dynamic View Models in ASP.NET MVC 3
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.
Derek Morrison
Web developer, lousy Russian student, ex-oboist, ex-Alabamian.
Updated on June 04, 2022Comments
-
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.