Asp.net-Mvc

是否有一種強命名的方法來刪除 ASP.NET MVC 中的 ModelState 錯誤

  • December 2, 2019

有沒有辦法在 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");

如果這是針對MVC 6的,建議使用ModelBindingHelper.ClearValidationStateForModel(Type, ModelStateDictionary, IModelMetadataProvider, string).

這是我的解決方案 -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);
           }
       }
   }

這是它的使用方法:

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
}

如果有人能找到改進它的方法(或者不必指定泛型類型參數),請告訴我。或者,如果它以不同的名稱存在於 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);
   }

可以這樣使用:

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

引用自:https://stackoverflow.com/questions/14008561