现在我们运行该程序,并通过Query String的形式提供作为Action方法Index参数的数据(?foo=123&bar=456&baz=789),我们可以看到界面上呈现出来的总是原始值,也是说我们在Action方法Index中对原始数据的修改没有起到任何效果。

  通过查看ASP.NET MVC框架自身的代码,我想这个问题的根源应该源于InputExtensions类型的InputHelper方法。如下所示,当InputHelper在指定表单元素值得时候,会先从当前ModelState中获取,如果该值在ModelState中不存在,才会从当前ViewData中获取。对于本例来说,ModelState中的值是原始值,ViewData的值采用修改后的值。
public static class InputExtensions
{
private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary<string, object> htmlAttributes);
}
private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary<string, object> htmlAttributes)
{

switch (inputType)
{

default:
{
string str4 = (string) htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(string));
tagBuilder.MergeAttribute("value", str4 ?? (useViewData ? htmlHelper.EvalString(fullHtmlFieldName, format) : str2), isExplicitValue);
goto Label_016C;
}
}

}
  我觉得rinsen的评论说得有道理,这也可能是为了保持请求的原始数据而作的妥协。不过我还是觉得这样的设计有违MVC的基本原则,MVC处理请求的流程很清楚:客户端(浏览器)向定义在Controller中的某个Action方法发送请求,Action方法处理这个请求,并呈现出相应的View来对请求做后的响应。换言之,终呈现怎么的View应该完全由Action方法决定,对于我们的例子来说,Action方法很明显的意图是将更新过的Model呈现出来。而且这是一种非常典型的场景:服务端对原始数据进行简单的加工后再呈现出来。
  其实我觉得严格来说也是无奈之举吧,
  拿Update场景来说
  比如说Model里面的某个Property可能是Int的,但是你传入的Form值却可能是任意的字符串,这时后台ModelState.IsValid是false,然后你需要返回View让用户继续修改,并把用户输入的值带入到Form中。
  这时候model其实是有的(反正不为null,而Property也是有默认值的:0)而回显显然不可能回显为0,而是用户的输入。
  所以这个角度看来ModelState的优先级是比较高的。
  [你总不能回显一个0,然后错误提示“你输入的不是数值类型”吧]