Ric*_*Net 5 c# asp.net-mvc modelstate razor
当MVC运行时ActionMethod,它将填充ModelState字典并使用a ModelBinder来构建ActionMethod参数(如果有的话).它这样做是两个GET和POST.这是有道理的.
后ActionMethod成功已经跑了,视图是使用所提供的剃刀,这在我的情况下,使用尽可能多的呈现HtmlHelper通话成为可能.到现在为止,您可能会想,"我知道MVC是如何工作的".等等,我到了那里.
当我们使用例如@Html.TextFor(m => m.Name)MVC时,使用可以在这里呈现标记的代码.
有趣的部分是在我们找到的文件的末尾:
switch (inputType)
{
case InputType.CheckBox:
// ... removed for brevity
case InputType.Radio:
// ... removed for brevity
case InputType.Password:
// ... removed for brevity
default:
string attemptedValue =
(string)htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ??
((useViewData)
? htmlHelper.EvalString(fullName, format)
: valueParameter), isExplicitValue);
break;
}
Run Code Online (Sandbox Code Playgroud)
这意味着它Modelstate用于获取提供的值Model.这对于a是有意义的,POST因为当存在验证错误时,您希望MVC使用用户已经提供的值来呈现视图.文档还说明了这种行为,StackOverflow上有几篇帖子证实了这一点.但它只是为说明POST,如能上可以看到这个线程,例如
但是,当为一个视图渲染时,也会使用此代码GET!这对我来说毫无意义.
请考虑以下操作方法:
public ActionResult GetCopy(Guid id)
{
var originalModel = this.repository.GetById(id);
var copiedModel = new SomeModel
{
Id = Guid.NewGuid(),
Name = originalModel.Name,
};
return this.View(copiedModel);
}
Run Code Online (Sandbox Code Playgroud)
用这个简单的剃刀标记:
@Html.TextBoxFor(m => m.Id)
@Html.TextBoxFor(m => m.Name)
Run Code Online (Sandbox Code Playgroud)
我希望视图显示新生成的GUID而不是Id原始模型.但是,视图显示Id传递给GET请求的actionmethod,因为ModelState字典包含带有名称的键Id.
我的问题不在于如何解决这个问题,因为这很容易:
ActionMethod参数重命名为不同的名称ModelState在返回ActionResult使用之前清除Modelstate.Clear()ModelState字典中的值,根本不提供Model视图.我的问题是:为什么这个程序为两个相同的GET和POST.是否有任何有效的用例来使用填充在a上ModelState提供Model的GET.
小智 3
不DefaultModelBinder区分 GET 和 POST 请求。虽然只有 MVC 团队可以确认他们为何做出该决定,但有一些有效的用例说明为什么ModelState应该在 GET 中使用(与在 POST 中使用的方式相同),因为您也可以向 GET 方法提交表单。
以航空公司预订应用程序为例,其中您有一个模型,其中包含用于选择出发和到达地点、日期和乘客数量(属性int)的属性,以及用于筛选结果的集合属性。GET 方法签名可能如下所示
public ActionResult Search(SearchViewModel model)
Run Code Online (Sandbox Code Playgroud)
该视图包含一个返回该方法的 GET 方法,并包含一个用于显示乘客数量的文本框。
禁用了 javascript 的(不太聪明的)用户在文本框中输入“TWO”并提交表单。您的方法返回视图,但不填充可用航班的集合,因为ModelState无效(值“TWO”对于 无效int),现在用户会看到一条错误消息,指出字段 Passengers 必须是数字。
如果使用模型值而不是ModelState值,则将显示关联的文本框0而不是"Two",从而使错误消息令人困惑(但它0是一个数字! - 我输入的内容发生了什么?)
| 归档时间: |
|
| 查看次数: |
208 次 |
| 最近记录: |