MVC @Html.EditorFor缓存Model的值是bug吧?小心入坑

MVC @Html.EditorFor缓存Model的值是bug吧?小心入坑

4505发表于2017-04-09

最近遇到一个ASP.NET mvc的问题。

需求是这样的:在新增页面新增成功后,页面输入的控件全部清空,并输出添加成功文字。

前台页面:


后台代码:

public ActionResult Add()
{
	var m = new MPart();
	return View(m);
}

[HttpPost]
public ActionResult Add([Bind(Exclude = "OID")]MPart model)
{
	if (string.IsNullOrEmpty(model.CodeNo))
		ModelState.AddModelError("error", "零件编号不能为空!");
	else if (string.IsNullOrEmpty(model.Name))
		ModelState.AddModelError("error", "零件名称不能为空!");
	if (ModelState.IsValid)
	{
		var user = LoginStateHelper.CurrentUserOrDefault;
		var r = PartService.Insert(model);
		ViewBag.Message = "添加成功!";
		model = new MPart();
		return View(model);
	}
	else
		return View(model);
}

运行结果出入意料的是:在新增页面新增成功后,页面输入的控件值并没有清空。可以从上面代码可以看到返回的是一个全新的Model对象,new了一个新模型对象。

结果如下图:

解决办法:

在返回视图之前加上:ModelState.Clear()

最后结果就是我所期望的。


原因分析:

InputHelper方法(Html.EditorFor)会先从当前ModelState中获取,如果该值在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;
        }
    }
…
}


同理@Html.TextBoxFor、@Html.EditorFor、@Html.EditorForModel也有同样的问题,用得时候要多注意,小心入坑。

延伸阅读:

http://www.cnblogs.com/artech/p/asp-net-mvc-bug.html

http://stackoverflow.com/questions/1775170/asp-net-mvc-modelstate-clear

小编蓝狐