码迷,mamicode.com
首页 > Web开发 > 详细

这算是ASP.NET MVC的一个大BUG吗?

时间:2015-07-17 18:27:50      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

这是昨天一个同事遇到的问题,我觉得这是一个蛮大的问题,而且应该不是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 += ":Changed";
        model.Baz += ":Changed";
        return View("index", mode);
    }
}
public class DemoModel
{
    public string Foo { get; set; }
    public string Bar { get; set; }
    public string Baz { get; set; }
}

对于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)
//第三种形式
@model DemoModel
@Html.EditorForModel

现在我们运行该程序,并通过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;
        }
    }
…
}

 

这算是ASP.NET MVC的一个大BUG吗?

标签:

原文地址:http://www.cnblogs.com/artech/p/asp-net-mvc-bug.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!