Подтвердить что ты не робот

Есть ли сильноименованный способ удаления ошибок ModelState в ASP.NET MVC

Есть ли способ удалить ошибки ModelState во время обратной передачи ASP.NET MVC без необходимости записи каждого из них вручную.

Скажем, у нас есть флажок 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");
4b9b3361

Ответ 1

Если это для MVC 6, предложите использовать ModelBindingHelper.ClearValidationStateForModel(Type, ModelStateDictionary, IModelMetadataProvider, string).

Ответ 2

Здесь мое решение - метод расширения RemoveFor() на ModelState, смоделированный после помощников HTML MVC:

    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);
 }