我正在开发一个大型的MVC3 web应用程序,并且对ModelState.IsValid方法有一个恼人的地方。
我几乎所有的控制器都在使用ModelState来验证发布的数据。这些视图都基于包含不同类的ViewModels,这些类显然包含可以标记为[Required]的属性。
我遇到的问题是,所需的属性有时并不是必需的,而我必须使用ModelState.Remove方法才能使ModelState.IsValid变为真。
我的问题是,通过使用ModelState.Remove,这是做事情的正确方法还是有更有效的方法。
发布于 2011-07-27 19:00:11
如果在两个不同的上下文中使用具有[Required]属性的相同视图模型,一个上下文需要该属性,另一个上下文不需要该属性,则需要像现在这样手动更改ModelState。
另一种方法是使用不同的视图模型。也许有一个基类,其中除了所讨论的required属性之外的所有属性。然后从它派生出两个视图模型,一个属性为where it required,另一个属性为not (我知道它是重复的)。您可以决定将它们完全分开,而不使用继承。
发布于 2012-12-23 11:54:56
这是我的解决方案-在ModelState上的一个RemoveFor()扩展方法,模仿MVC HTML helpers:
public static void RemoveFor<TModel>(this ModelStateDictionary modelState,
Expression<Func<TModel, object>> expression)
{
string expressionText = ExpressionHelper.GetExpressionText(expression);
foreach (var ms in modelState.ToArray())
{
if (ms.Key.StartsWith(expressionText + ".") || ms.Key == expressionText)
{
modelState.Remove(ms);
}
}
}下面是它的用法:
if (model.CheckoutModel.ShipToBillingAddress == true)
{
// REUSE BILLING ADDRESS FOR SHIPPING ADDRESS
ShoppingCart.ShippingAddress = ShoppingCart.BillingAddress;
// REMOVE MODELSTATE ERRORS FOR SHIPPING ADDRESS
ModelState.RemoveFor<SinglePageStoreModel>(x => model.CheckoutModel.ShippingAddress);
}在回答你的问题时,我相信肯定有这样做的用例,像这样的强类型助手会让它看起来更好-如果你关心很多魔法字符串,也更容易证明这一点。
发布于 2011-07-27 19:00:59
从根本上说,您的问题是虽然您的类是用Required装饰的,但这并不总是正确的。如果你在一个不真实的上下文中操作,你真的应该使用一个没有将属性定义为Required的类。
您真的应该使用为其特定用法正确定义的ViewModel,这可能意味着复制某些类。ViewModel与UI的实现相关联,虽然它可以使用域模型中的类,但这并不总是正确的做法。
如果做不到这一点,选项是要么不使用ModelState.IsValid,要么继续使用ModelState.Remove。
但从逻辑上讲,您的ViewModel应该是“可验证的”,而不必忽略某些验证错误。
https://stackoverflow.com/questions/6843171
复制相似问题