asp.net-mvc - List<dynamic> 的奇怪 Razor 行为

标签 asp.net-mvc razor

这是我的 Controller 的代码:

 IQueryable<Foo> foos = dbContext.Foos.Where(...);

 return View(foos);

这个 Razor 代码(cshtml)有效 :
@model IQueryable<Foo>

@{
     IQueryable<Foo> foos = Model;

     var projected = foos.Select(e => new 
     {
          fooId = e.FooId,
          bar = new 
          {
              barId = e.Foo.BarId
          }
     }).ToList();
}

@foreach (var x in projected)
{
     <span>@x.fooId</span><br />
}

但是这个 Razor 代码(cshtml)不起作用,几乎是一样的!:
@model IQueryable<Foo>

@{
     IQueryable<Foo> foos = Model;

     var projected = foos.Selected(Foo.Projection()).ToList()
}

@foreach (var x in projected)
{
     <span>@x.fooId</span><br />
}
Foo.Projection()是一个我经常重复使用的静态方法:
    public static Expression<Func<Foo, dynamic>> Projection()
    {
        return e => new
        {
            fooId = e.FooId,
            bar = new 
            {
                barId = e.Foo.BarId
            }
        }
    }

我遇到了那个著名的错误:'object' does not contain definition for 'fooId' ,在这里讨论:MVC Razor dynamic model, 'object' does not contain definition for 'PropertyName' - 但这些答案都没有帮助我。

接受的答案是:“现在 MVC 3 直接支持动态,不再需要下面的技术”,所以我也尝试返回预计的 List<dynamic>到 View (“准备使用,不需要投影”),它也没有工作(得到同样的错误)。这是该尝试的代码:

Controller 代码:
 List<dynamic> foos = dbContext.Foos.Select(Foo.Projection()).ToList();

 return View(foos);

查看代码:
 @model dynamic

 etc.

编辑:使用调试器,我可以检查(在抛出异常之后)该项目确实有 "a definition for..." (在示例代码中,该项目是 x ,但这里是 lot )

Debugger proof

最佳答案

当您使用 dynamic您指示编译器使用反射来调用方法和访问属性。在您的情况下,您以这种方式访问​​的对象是匿名类型,匿名类型是 internal到创建它们的程序集中。

为 Razor View 生成的代码位于单独的程序集中,尝试反射(reflect)在 Controller 中创建的匿名类型将失败。调试器不受此限制的影响,因此当反射失败并引发异常时,您仍然可以在调试器中检查匿名类型的属性。

这也解释了为什么您的代码在 Razor View 中创建匿名类型时有效。然后你使用 dynamic 生成的代码能够反射(reflect)匿名类型,因为它是在同一个程序集中声明的。

本质上,在 MVC Razor 中,当在 Controller 中声明匿名类型时,您无法在 View 中使用它们。您对 dynamic 的使用通过生成一个难以理解的运行时错误来隐藏这个潜在的问题。

要解决您的问题,您可以创建特定的公共(public)类型而不是使用内部匿名类型,或者您可以 convert the anonymous type to an ExpandoObject 在 Controller 中。

关于asp.net-mvc - List<dynamic> 的奇怪 Razor 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28706578/

相关文章:

c# - 如何将 lambda 传递给 Razor 辅助方法?

asp.net-mvc - 在 Razor 中使用 Html.EditorForModel 渲染时,ASP.Net [HiddenInput] 数据属性不起作用?

c# - 使用正则表达式的 Asp.Net 模型验证。寻找特定的字符串而不仅仅是一个字母

asp.net-mvc-3 - 如何从 MVC 3 中的区域渲染主项目中的部分?

javascript - 无法将 HTML 文本设置到 InnerHtml 属性中

c# - @Html.DropDownListFor如何设置默认值

c# - Miniprofiler 中的渲染步骤发生了什么?

javascript - 查看源代码: having the incorrect JSON rendering ToString() C# MVC

c# - 将自签名ssl证书添加到gcp容器化.net核心Web虚拟机实例

c# - 什么是 ASP.Net MVC 操作结果?