加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 使用List的奇怪剃刀行为

发布时间:2020-12-16 06:33:46 所属栏目:asp.Net 来源:网络整理
导读:这是我的控制器代码: IQueryableFoo foos = dbContext.Foos.Where(...); return View(foos); 这个剃刀代码(cshtml)效果很好: @model IQueryableFoo@{ IQueryableFoo foos = Model; var projected = foos.Select(e = new { fooId = e.FooId,bar = new { bar
这是我的控制器代码:

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

 return View(foos);

这个剃刀代码(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 />
}

但这个剃刀代码(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’不包含’fooId’的定义,这里讨论的是:MVC Razor dynamic model,‘object’ does not contain definition for ‘PropertyName’ – 但这些答案都没有帮助我.

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

控制器代码:

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

 return View(foos);

查看代码:

@model dynamic

 etc.

编辑:使用调试器,我能够检查(在抛出异常之后)项目确实具有“…的定义”(在示例代码中项目为x,但这里是很多)

解决方法

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

为Razor视图生成的代码位于单独的程序集中,并且尝试反映在控制器中创建的匿名类型将失败.调试器不受此限制的影响,因此当反射失败并抛出异常时,您仍然可以检查调试器中匿名类型的属性.

这也解释了为什么在Razor视图中创建匿名类型时代码可以正常工作.然后,使用dynamic生成的代码能够反映出anonmyous类型,因为它是在同一个程序集中声明的.

基本上,在MVC Razor中,当在控制器中声明匿名类型时,您无法在视图中使用匿名类型.您对动态的使用是通过生成难以理解的运行时错误来隐藏此基础问题.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读