Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Razor 为什么Html帮助程序为视图模型的子项的属性添加前缀?_Razor - Fatal编程技术网

Razor 为什么Html帮助程序为视图模型的子项的属性添加前缀?

Razor 为什么Html帮助程序为视图模型的子项的属性添加前缀?,razor,Razor,我有一个具有单个子实体和各种其他属性的视图模型 在我的视图中,我想显示子实体的表单。 使用以下代码: @Html.HiddenFor(model => model.Item.ItemID) @Html.EditorFor(model => model.Item.Title) @Html.ValidationMessageFor(model => model.Item.Title) 生成以下输出: <input id="Item_ItemID" name="Item.I

我有一个具有单个子实体和各种其他属性的视图模型

在我的视图中,我想显示子实体的表单。 使用以下代码:

@Html.HiddenFor(model => model.Item.ItemID)
@Html.EditorFor(model => model.Item.Title)
@Html.ValidationMessageFor(model => model.Item.Title)
生成以下输出:

<input id="Item_ItemID" name="Item.ItemID" type="hidden" value="234" />
因此,前一个输出在提交表单时会导致错误,因为表单元素与子实体上的属性不对应

我知道我可以通过硬编码隐藏字段来解决这个问题

<input id="ItemID" name="ItemID" type="hidden" value="@Model.Item.ItemID" />
我知道可以将html属性传递给该方法,也可以编写自己的扩展方法,但当涉及数据验证和jQuery时,事情会变得更加复杂,即以下代码:

@Html.HiddenFor(model => model.Item.ItemID)
@Html.EditorFor(model => model.Item.Title)
@Html.ValidationMessageFor(model => model.Item.Title)
生成以下代码:

<input class="text-box single-line" data-val="true" data-val-required="The Title field is required." id="Item_Title" name="Item.Title" type="text" value="Some text" />
<span class="field-validation-valid" data-valmsg-for="Item.Title" data-valmsg-replace="true"></span>

因此,需要一种优雅的方法来保持属性名称的同步

那么,有人能回答为什么HtmlHelper会为视图模型的子项的属性添加前缀吗?
作为后续问题,是否有其他简洁的方法防止前缀被添加

HTML帮助程序是根据模型绑定约定构建的。例如,我假设您有以下模型:

public class MyViewModel
{
    public ItemViewModel Item { get; set; }

    // ... other properties
}

public class ItemViewModel
{
    public int ItemID { get; set; }
}
相应的视图被强类型化为
MyViewModel

因此,当您使用:

@Html.HiddenFor(model => model.Item.ItemID)
助手将生成:

<input id="Item_ItemID" name="Item.ItemID" type="hidden" value="234" />
我猜您的问题来自这样一个事实:控制器操作将
ItemViewModel
作为参数,而不是
MyViewModel

[HttpPost]
public ActionResult Process(ItemViewModel model)
{
    // model.ItemID will not be correctly bound here from the hidden field value
}
因此,您可以使用
[Bind]
属性并指定前缀来帮助模型绑定器:

[HttpPost]
public ActionResult Process([Bind(Prefix="Item")] ItemViewModel model)
{
    // model.ItemID will be correctly bound here from the hidden field value
}
或者简单地设计另一个视图模型,从中剥离所有不必要的属性,只保留
属性。现在,您的控制器操作可以采用这个专门设计的视图模型


因此,正如您在一天结束时所看到的,如果您正确地设计了视图模型,您可以很好地控制模型绑定。所有这些都是关于ASP.NET MVC中的视图模型。他们解决了所有问题。

谢谢@Darin。您的判断是正确的,控制器操作需要ItemViewModel。添加Bind属性解决了我最初的问题,而不必求助于我的任何解决方法。
[HttpPost]
public ActionResult Process([Bind(Prefix="Item")] ItemViewModel model)
{
    // model.ItemID will be correctly bound here from the hidden field value
}