Why do I get a variable scope error (CS0136) in a Html.HiddenFor?

别来无恙 提交于 2019-12-25 05:22:24

问题


Here is a stripped-down code snippet from a MVC3/Razor view file:

@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 *@

The title shows on the first row. It also shows inside the form. But trying to use it in the HiddenFor I get error CS0136: A local variable named 'item' cannot be declared in this scope because it would give a different meaning to 'item', which is already used in a 'parent or current/child' scope to denote something else

I don't get why that would be the case; in item => item.Title the first "item" is effectively just a parameter name in an anonymous function, isn't it?

When I change it to: @Html.HiddenFor(s => s.Title) I get error CS1963, An expression tree may not contain a dynamic operation.

Background: the intention is to have two table rows per entry in Model.Stuff.Items, the first giving current information as static HTML, the second an edit form for it. (One or the other will be hidden at any time using javascript.) The form will submit to another action on this controller. All the forms submit to the same URL; the hidden values will identify which row is being updated.


回答1:


Use @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:


I don't get why that would be the case; in item => item.Title the first "item" is effectively just a parameter name in an anonymous function, isn't it?

Yes, but it's introducing another variable with the same name into a scope which already includes a local variable of that name. You just can't do that. It would make it ambiguous when you use item within the lambda expression - it could mean the parameter, or it could mean the iteration variable.

Note that this has nothing to do with MVC or Razor. You get the same error with this code:

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

From section 17.15.1 of the C# 5 spec:

The scope of the parameters of the anonymous function is the anonymous-function-body. (§3.7) Together with the parameter list (if given) the anonymous-method-body constitutes a declaration space (§3.3). It is thus a compile-time error for the name of a parameter of the anonymous function to match the name of a local variable, local constant or parameter whose scope includes the anonymous-method-expression or lambda-expression.




回答3:


For the CS1963 part of the problem, that is resolved by setting the @Model at the top of this partial view file, and then passing that as the 2nd parameter of HTML.Partial()

So, in my outer view, the Html.Partial line changed to look this like:

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

Then at the top of partial.examples.cshtml, I added:

@model IEnumberable<Type.Of.Items>

And the foreach line changed to be:

@foreach (var item in Model){

Finally, to get rid of the CS0136 error, as Yasser suggested:

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

(And thanks to Jon for explaining why item => item.Title was not allowed.)



来源:https://stackoverflow.com/questions/12793537/why-do-i-get-a-variable-scope-error-cs0136-in-a-html-hiddenfor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!