我发现对ASP.NET MVC非常讨厌的一点是,在POST请求期间,ModelState值非常持久,使用@ Html。*扩展方法。我知道ModelState允许持久存在无效的用户输入值,但是,即使对于用户输入值有效的属性,MVC对ModelState的处理也会继续。有时,这是不良行为。
例如,如果您在URL中有ID,并且您在视图模型中将ID属性设置为不同的值(这是一个好的迹象,ID名称需要更具体,但请耐心等待) ,您设置的值将在GET请求期间生成,但在POST期间,将使用ModelState中的值,该值将来自路径。
发布的值也会发生这种情况。如果由于某种原因,您需要更改来自客户端的值,则将忽略模型中的新值;你还必须(或者更新)更新ModelState。
为解决这种不一致问题,我已将此动作过滤器添加到我的MVC项目中作为全局过滤器:
public class RemoveValidModelStateFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var modelState = filterContext.Controller.ViewData.ModelState;
var keys = modelState.Keys.ToArray();
foreach (var key in keys)
{
var entry = modelState[key];
if (entry.Errors.Count == 0)
modelState.Remove(key);
}
}
}
到目前为止,它一直很适合我,但我很好奇我是否无意中造成任何问题或失去功能。我只在我可以完全控制的新项目和项目上使用它,因此它不会创建隐藏的值,而不会传达值。
我可以看到其他开发人员在处理我的项目时可能会感到困惑,但我不知道任何其他副作用。
答案 0 :(得分:0)
ModelState用于重新填充表单上未成功提交并读入模型的任何值。然后使用这些值重新填充表格。我认为最好的例子是用于验证目的,例如你有一个模特:
public class TestModel
{
public DateTime { get;set;}
}
您的控制器可能如下所示:
public class TestController : Controller
{
public ActionResult Index()
{
return View(new TestModel());
}
[HttpPost]
public ActionResult Index(TestModel model)
{
return View(model);
}
}
在您的视图中,您可以将该日期表示为文本框输入。如果用户键入有效日期并提交表单,则页面将使用提交的模型中该文本框中填充的值重新加载。到现在为止还挺好。但是,如果用户输入无效日期,则TestModel不能被打包(因为该属性将无效),因此MVC使用ModelState来重新填充文本框。如果每次都清除模型状态,最终会出现验证错误,但会出现空白文本框而不是用户先前输入的内容。
在您的情况下可能不是问题,但我会谨慎地清除所有操作,以防您以后需要此功能。