是否有一种强有力的方法来删除ASP.NET MVC中的ModelState错误

Sim*_*ver 13 asp.net-mvc modelstate

有没有办法在ASP.NET MVC回发期间删除ModelState错误,而无需手动编写每个错误.

假设我们有一个复选框Billing Same As Shipping,我们希望忽略用户ShippingAddress在检查时所写的内容 - 通常你可能会做的就是这个.

ModelState.Remove("Checkout.ShipppingAddress.FirstName");
ModelState.Remove("Checkout.ShipppingAddress.LastName");
ModelState.Remove("Checkout.ShipppingAddress.Address1");
ModelState.Remove("Checkout.ShipppingAddress.Address2");
...
ModelState.Remove("Checkout.ShipppingAddress.ZipCode");
Run Code Online (Sandbox Code Playgroud)

Sim*_*ver 26

这是我的解决方案 - 一个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 + "."))
            {
                modelState.Remove(ms);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

以下是它的使用方法:

if (model.CheckoutModel.ShipToBillingAddress == true) 
{
    // COPY BILLING ADDRESS --> SHIPPING ADDRESS
    ShoppingCart.ShippingAddress = ShoppingCart.BillingAddress;

    // REMOVE MODELSTATE ERRORS FOR SHIPPING ADDRESS
    ModelState.RemoveFor<SinglePageStoreModel>(x => x.CheckoutModel.ShippingAddress);
}

if (ModelState.IsValid) 
{
     // should get here now provided billing address is valid
}
Run Code Online (Sandbox Code Playgroud)

如果有人可以看到改进它的方法(或者不必指定泛型类型参数),那么请告诉我.或者,如果MvcFutures中存在不同的名称,我宁愿切换到那个名称.

虽然我在这里帮助检查ModelState是否对某个"树"有效

    public static bool IsValidFor<TModel, TProperty>(this TModel model,
                                                     System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression,
                                                     ModelStateDictionary modelState)
    {
        string name = ExpressionHelper.GetExpressionText(expression);

        return modelState.IsValidField(name);
    }
Run Code Online (Sandbox Code Playgroud)

哪个可以这样使用:

 if (model.IsValidFor(x => x.CheckoutModel.BillingAddress, ModelState))
 {
     _debugLogger.Log("Billing Address Valid", () => ShoppingCart.BillingAddress);
 }
Run Code Online (Sandbox Code Playgroud)

  • 如果你喜欢括号而不是尖括号,你可以在表达式中指定模型类型而不是泛型参数:ModelState.RemoveFor((SinglePageStoreModel x)=> x.CheckoutModel.ShippingAddress); (2认同)

小智 4

如果这是针对MVC 6,建议使用ModelBindingHelper.ClearValidationStateForModel(Type, ModelStateDictionary, IModelMetadataProvider, string).