2

警告:这可能是对 C# 动态关键字的不当使用,我可能应该使用强类型视图模型,但是......

我试图通过将 C# 4 动态类型传递给我的视图来避免创建强类型视图模型。我的控制器中有这个:

    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);
    }

...在我看来(我正在使用 MVC 3 的 Razor 视图引擎):

        @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>

我不喜欢遍历 LINQ 结果以形成动态对象列表的方式。

我想在 LINQ 查询中初始化每个 ExpandoObject,但这似乎不受支持

我尝试将查询结果转换为 List,但这不起作用,因为您无法将匿名类型转换为动态类型。

4

2 回答 2

4

就像你说的,不支持。(我不是说不支持动态视图模型 - 我是说你想要做的不是)

您可能可以整理 LINQ 查询,但最终您最好的选择是简单地创建一个自定义视图模型。说真的,这将花费您大约 30 秒的时间。

我知道动态是新的和很酷的,但是如果你在这种情况下坚持使用自定义视图模型,你的代码会更整洁,更容易维护。

我只会在非常简单的场景中使用动态视图模型——大多数时候你可能想要坚持我们一直在做的事情——自定义视图模型。

于 2010-09-22T06:53:17.697 回答
0

好的,您可以执行以下操作,但我不建议这样做。创建一个类似于下面的静态方法

public static IHtmlString DisplayProperty(object obj, string property) {
    return new HtmlString(TypeDescriptor.GetProperties(obj)[property].GetValue(obj).ToString());
}

然后在您的 cshtml 文件中进行以下调用(确保使用正确的命名空间)

<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>

我不会推荐这个,但它是一个不需要模型的解决你的问题的方法。

于 2010-09-21T14:32:54.247 回答