为什么我不能通过lambda表达式参数访问模型的属性?

时间:2018-01-01 22:11:53

标签: c# razor lambda asp.net-core

考虑Razor页面后面的代码隐藏文件。

public class IndexModel : PageModel
{
    MovieContext Context { get; }

    public IndexModel(MovieContext context)
    {
        Context = context;
    }

    public IList<Movie> Movies { get; set; }

    public async Task OnGetAsync()
    {
        Movies = await Context.Movie.ToListAsync();
    }
}

修剪过的Razor页面如下:

@page
@model IndexModel
@foreach (var item in Model.Movies)
{
    @Html.DisplayFor(modelItem =>item.Title)
}

问题

仅出于学术目的,假设我不能捕获lambda表达式中的外部变量。

为什么我不能使用

@Html.DisplayFor(modelItem => modelItem.Movies[modelItem.Movies.IndexOf(item)].Title)

而不是

@Html.DisplayFor(modelItem =>item.Title)

1 个答案:

答案 0 :(得分:2)

DisplayFor之类的助手接受一个表达式的参数。不是行动。它没有被执行;它被解析了。

例如,如果你写

DisplayFor( a => a.Name );

...框架只需调用a.Name即可获取值。相反,它将反映包含a.Name的表达式,并确定引用的类型和属性。然后它查看属性的类型和属性,例如DataAnnotation属性,用于确定显示属性所需的内容。

因此,您可以提供的参数种类有限。 documentation描述了它的使用方式:

  
      
  • 如果属性类型为基本类型(整数,字符串等),则该方法呈现表示属性值的字符串。

  •   
  • 如果属性类型为Boolean,则该方法为复选框呈现HTML输入元素。例如,名为Enabled的布尔属性可能会呈现如下标记:

  •   
     

<input class="check-box" disabled="disabled" ="checkbox" checked="checked" />

     
      
  • 如果使用数据类型属性注释属性,则该属性指定为该属性生成的标记。例如,如果属性标记有EmailAddress属性,则该方法将生成包含使用mailto协议配置的HTML锚点的标记,如以下示例所示:
  •   
     

<a href='mailto:joe@contoso.com'>joe@contoso.com</a>

     
      
  • 如果对象包含多个属性,则对于每个属性,该方法都会生成一个字符串,该字符串包含属性名称的标记和属性值的标记。
  •   
相关问题