为什么我在Html.HiddenFor中得到变量范围错误(CS0136)?

时间:2012-10-09 05:47:10

标签: c# asp.net-mvc-3 razor

以下是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一个名为&#39; item&#39;的局部变量不能在此范围内声明,因为它会对“项目”提供不同的含义,该项目已在父母或当前/儿童中使用。范围表示别的东西

我不知道为什么会这样;在item => item.Title第一个&#34;项目&#34;实际上只是匿名函数中的参数名称,不是吗?

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

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

3 个答案:

答案 0 :(得分:2)

  

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

是的,但它将另一个具有相同名称的变量引入已包含该名称的局部变量的范围。你不能这样做。当你在lambda表达式中使用item时,它会使它变得模糊 - 它可能意味着参数,或者它可能意味着迭代变量。

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

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

来自C#5规范的第17.15.1节:

  

匿名函数的参数范围是匿名函数体。 (§3.7)与参数列表(如果给定)一起,anonymous-method-body构成一个声明空间(§3.3)。因此,匿名函数的参数名称与本地变量,本地常量或参数的名称匹配,编译时错误,其范围包括anonymous-method-expression或lambda-expression。

答案 1 :(得分: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>
}

答案 2 :(得分: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。)