问题
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.
回答1:
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.
回答2:
Ok, you could do the following, but I wouldn't recommend it. Create a static method similar to the following
public static IHtmlString DisplayProperty(object obj, string property) {
return new HtmlString(TypeDescriptor.GetProperties(obj)[property].GetValue(obj).ToString());
}
Then in your cshtml file make the following call (make sure to using your proper namespace)
<tbody>
@foreach (var item in Model) {
<tr>
<td>@DisplayProperty(x, "RateCodeName")</td>
<td>@DisplayProperty(x, "Year")</td>
<td>@DisplayProperty(x, "Rate")</td>
<td>>@DisplayProperty(x, "Comment")</td>
</tr>
}
</tbody>
I wouldn't recommend this though but it is a solution to your problem that doesn't require a model.
来源:https://stackoverflow.com/questions/3758612/simplest-way-to-do-dynamic-view-models-in-asp-net-mvc-3