使用ModelState.Remove处理ModelState是否正确?

Hes*_*sky 18 asp.net-mvc modelstate asp.net-mvc-3

我正在开发一个大型的MVC3 Web应用程序,并对该ModelState.IsValid方法感到烦恼.

几乎所有的控制器都使用ModelState,以验证发布的数据.视图都基于包含不同类的ViewModel,这些类显然包含可以标记为的属性[Required].

我遇到的问题是有时不需要所需的属性,我必须使用该ModelState.Remove方法才能ModelState.IsValid成为现实.

我的问题是使用ModelState.Remove,这是正确的做事方式还是更有效的方法.

Sim*_*ver 20

这是我的解决方案 - 一个RemoveFor()扩展方法ModelState,模仿MVC HTML帮助器:

    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);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

以下是它的使用方法:

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);
}
Run Code Online (Sandbox Code Playgroud)

因此,在回答你的问题时,我相信肯定有一些用例,这是正确的方法,这样一个强类型的助手让它看起来更好 - 如果你关心很多,也更容易证明魔术弦.

  • @Rookian在什么方面复杂?你根本不喜欢删除ModelState的想法 - 或者你没有遇到像ModelState.Remove("CheckoutModel.ShippingAddress.City")这样的代码的问题,并且不需要这样做.我发现这是一种更安全的做事方式,如果我改变了我在编译时发现的东西的名称.我总是讨厌删除模型状态,但有时你只需要这样做,而且我对这种方法更加舒适.好奇你的更详细的意见是什么 (3认同)
  • 我喜欢这个解决方案,我必须往返一个模型被回发查看,这让我的生活更轻松.我发现我发现了一个错误,我正在删除一个数组的字段.以"."结尾的匹配项 失败所以我将`ms.Key.StartsWith(expressionText +"[")`添加到if条件中. (2认同)

Rus*_*Cam 15

如果您[Required]在两个不同的上下文中使用具有属性的相同视图模型,一个需要属性,另一个不需要属性,那么您需要手动更改ModelState您正在执行的操作.

另一种方法是使用不同的视图模型.也许有一个基类,除了所讨论的必需属性外,还有所有属性.然后从中导出两个视图模型,一个具有所需的属性,另一个具有不属性的属性(我知道它是重复的).您可以决定将它们完全分开,而不是使用继承.


Ste*_*gan 11

从根本上说,您的问题是,虽然您的课程使用[必需]进行修饰,但并非总是如此.如果您在不正确的上下文中操作,那么您应该使用未将属性定义为[必需]的类.

您应该使用为其特定用法正确定义的ViewModel,这可能意味着复制某些类.ViewModel与UI的实现相关联,虽然它可能使用域模型中的类,但它并不总是正确的.

如果不这样做,选项要么不使用ModelState.IsValid,要么继续使用ModelState.Remove.

但从逻辑上讲,将ViewModel设置为"可验证"是有意义的,而不必忽略某些验证错误.