0

这是来自 MVC3/Razor 视图文件的精简代码片段:

@foreach (var item in Model.Stuff.Items){
<tr>
  <td>@item.Title</td>
</tr>
<tr>
  <td>
    @using (Html.BeginForm()) {
        @item.Title
        @Html.HiddenFor(item => item.Title)
    }
  </td>
</tr>
}  @* End of Items foreach loop *@

标题显示在第一行。它还显示在表单内部。但是尝试在HiddenFor我收到错误CS0136中使用它:无法在此范围内声明名为“item”的局部变量,因为它会给“item”赋予不同的含义,该“item”已在“父级或当前/子级”中使用表示其他东西的范围

我不明白为什么会这样。在item => item.Title第一个“项目”中实际上只是匿名函数中的参数名称,不是吗?

当我将其更改为:@Html.HiddenFor(s => s.Title)我收到错误 CS1963,表达式树可能不包含动态操作。

背景:目的是在 Model.Stuff.Items 中的每个条目有两个表行,第一个以静态 HTML 的形式提供当前信息,第二个是它的编辑表单。(其中一个或另一个将在任何时候使用 javascript 隐藏。)表单将提交给此控制器上的另一个操作。所有表单都提交到同一个 URL;隐藏值将标识正在更新的行。

4

3 回答 3

3

我不明白为什么会这样。在 item => item.Title 中,第一个“item”实际上只是匿名函数中的参数名称,不是吗?

是的,但是它将另一个具有相同名称的变量引入到已经包含该名称的局部变量的范围中。你就是不能那样做。当您在 lambda 表达式中使用时,它会变得模棱两可item——它可能表示参数,也可能表示迭代变量。

请注意,这与 MVC 或 Razor 无关。使用此代码您会得到相同的错误:

int x = 0;
Func<int, int> y = x => x;

从 C# 5 规范的第 17.15.1 节:

匿名函数的参数范围是anonymous-function-body。(第 3.7 节)与参数列表(如果给定)一起,匿名方法体构成声明空间(第 3.3 节)。因此,匿名函数的参数名称与范围包括匿名方法表达式或 lambda 表达式的局部变量、局部常量或参数的名称匹配是编译时错误。

于 2012-10-09T05:49:25.103 回答
2

采用@Html.HiddenFor(x => item.Title)

@foreach (var item in Model.Stuff.Items){
<tr>
  <td>@item.Title</td>
</tr>
<tr>
  <td>
    @using (Html.BeginForm()) {
        @item.Title
        @Html.HiddenFor(x => item.Title)
    }
  </td>
</tr>
}
于 2012-10-09T05:53:23.620 回答
1

对于问题的 CS1963 部分,可以通过在此部分视图文件的顶部设置 @Model,然后将其作为 HTML.Partial() 的第二个参数传递来解决

因此,在我看来,Html.Partial 行变为如下所示:

 @Html.Partial("partial.example",Model.Stuff.Items)

然后在 partial.examples.cshtml 的顶部,我添加了:

@model IEnumberable<Type.Of.Items>

并且 foreach 行更改为:

@foreach (var item in Model){

最后,要摆脱 CS0136 错误,正如 Yasser 建议的那样:

@Html.HiddenFor(x => item.Title)

(感谢 Jon 解释为什么item => item.Title不允许。)

于 2012-10-09T09:24:59.690 回答