当 MVC 运行时ActionMethod
它将填充ModelState
字典并使用ModelBinder
建立ActionMethod
参数(如果有)。它对两者都这样做GET
and POST
。这是有道理的。
之后ActionMethod
已成功运行,视图使用提供的剃刀进行渲染,在我的例子中使用了尽可能多的剃刀HtmlHelper
尽可能打电话。到目前为止,您可能会想,“是的,我知道 MVC 是如何工作的”。等一下,我这就到了。
当我们使用例如@Html.TextFor(m => m.Name)
MVC使用的代码可以是here https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/InputExtensions.cs来渲染标签。
有趣的部分是在文件的末尾,我们发现:
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;
}
这意味着Modelstate
用于获取超过所提供的值Model
。这对于POST
因为当出现验证错误时,您希望 MVC 使用用户已提供的值来渲染视图。文档也说明了这种行为,StackOverflow 上有几篇帖子证实了这一点。但它的规定仅适用于POST
,如上所示这个线程 https://stackoverflow.com/a/8191658/3294832例如
然而,当渲染视图时也会使用此代码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);
}
使用这个简单的剃刀标记:
@Html.TextBoxFor(m => m.Id)
@Html.TextBoxFor(m => m.Name)
我希望视图显示新生成的GUID
而不是Id
原始模型的。然而该视图显示Id
传递给action方法GET
请求因为ModelState
字典包含一个带有名称的键Id
.
我的问题不是如何解决这个问题,因为这相当简单:
- 重命名
ActionMethod
参数不同
- 清除
ModelState
在返回之前ActionResult
using Modelstate.Clear()
- 替换中的值
ModelState
字典并且不提供Model
根本看不到风景。
我的问题是:
为什么这个过程对于两者来说是相同的GET
and POST
。是否有使用填充的有效用例ModelState
超过提供的Model
on a GET
.