这算是ASP.NET MVC的一个大BUG吗?
这是昨天一个同事遇到的问题,我觉得这是一个蛮大的问题,而且不像是ASP.NET MVC的设计者有意为之,换言之,这可能是ASP.NET MVC的一个Bug(不过也有可能是保持原始请求数据而作的妥协)。StackOverflow上也有对这个问题的描述http://stackoverflow.com/questions/1775170/asp-net-mvc-modelstate-clear 闲话少说,我们通过一个简单的问题重新这个问题。首先我们 定义了如下一个默认的HomeController,它具有一个默认Action方法Index。该方法接受一个类型为DemoModel的参数,定义其中的逻辑非常简单:我们对该参数的三个属性略加修改后,将其作为Model呈现在对应的View中。 public class HomeController : Controller { public ActionResult Index(DemoModel model) { model.Foo += ":Changed"; model.Bar += ; model.Baz += ; return View(index,model); } } DemoModel { string Foo { get; set; } string Bar { string Baz { ; } } 对于Action方法Index对应的View(Index.cshtml),我们可以采用如下三种定义方式将Model对象以编译模式呈现出来。 //第一种形式
@model DemoModel
@Html.LabelFor(m=>m.Foo)
@Html.TextBoxFor(m => m.Foo)
@Html.LabelFor(m => m.Bar)
@Html.TextBoxFor(m => m.Bar)
@Html.LabelFor(m => m.Baz)
@Html.TextBoxFor(m => m.Baz)
//第二种形式
@model DemoModel
@Html.LabelFor(m=>m.Foo)
@Html.EditorFor (m => m.Foo)
@Html.LabelFor(m => m.Bar)
@Html.EditorFor (m => m.Bar)
@Html.LabelFor(m => m.Baz)
@Html.EditorFor (m => m.Baz) 现在我们运行该程序,并通过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> htmlAttributes); } private static MvcHtmlString InputHelper(HtmlHelper htmlHelper,1)"> 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呈现出来。而且这是一种非常典型的场景:服务端对原始数据进行简单的加工后再呈现出来。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – StyleBundle索引超出了数组的边界
- 如何从asp.net中的客户端网络摄像头捕获图像
- asp.net-mvc – Html.RenderPartial和Html.Rende
- asp.net – 为什么Request.IsSecureConnection返
- asp.net-identity-2 – GenerateEmailConfirmati
- asp.net-mvc – 如何保持MVC JQuery Ajax POSTs
- asp.net-mvc – ASP.NET MVC PostAuthorizeReque
- asp.net-mvc – Kendoui MVC EditorTemplateName
- asp.net – 在不过度使用meta:resourcekey的情况
- asp.net-mvc – 在控制器中创建操作链接