有条件地使用DataAnnotations验证ASP.NET MVC模型的部分?

Sim*_*ver 9 asp.net-mvc data-annotations

我的页面上有某些面板在某些情况下是隐藏的.

例如,我可能有"帐单邮寄地址"和"送货地址",如果选中"ShippingSameAsBilling"复选框,我不想验证"送货地址".

我试图使用ASP.NET MVC 2(预览1)的新DataAnnotations功能来实现这一目标.

我需要防止在未显示"送货地址"时对其进行验证,并且需要找到实现此目的的方法.我主要讨论服务器端而不是使用jquery.

我怎样才能做到这一点?我有几个想法,与自定义模型绑定有关,但我目前最好的解决方案如下.有关此方法的任何反馈?

Sim*_*ver 6

对于CheckoutModel我使用这种方法(大多数字段隐藏):

[ModelBinder(typeof(CheckoutModelBinder))]
public class CheckoutModel : ShoppingCartModel
{        
    public Address BillingAddress { get; set; }
    public Address ShippingAddress { get; set; }
    public bool ShipToBillingAddress { get; set; }
}

public class Address
{
    [Required(ErrorMessage = "Email is required")]
    public string Email { get; set; }

    [Required(ErrorMessage = "First name is required")]
    public string FirstName { get; set; }

    [Required()]
    public string LastName { get; set; }

    [Required()]
    public string Address1 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

自定义模型绑定器会删除以"ShippingAddress"开头的字段的所有ModelState错误(如果找到).然后'TryUpdateModel()'将返回true.

    public class CheckoutModelBinder : DefaultModelBinder
    {
        protected override void OnModelUpdated(ControllerContext controllerContext,
                                               ModelBindingContext bindingContext) {

            base.OnModelUpdated(controllerContext, bindingContext);

            var model = (CheckoutModel)bindingContext.Model;

            // if user specified Shipping and Billing are the same then 
            // remove all ModelState errors for ShippingAddress
            if (model.ShipToBillingAddress)
            {
                var keys = bindingContext.ModelState.Where(x => x.Key.StartsWith("ShippingAddress")).Select(x => x.Key).ToList();
                foreach (var key in keys)
                {
                    bindingContext.ModelState.Remove(key);
                }
            }
        }    
    }
Run Code Online (Sandbox Code Playgroud)

更好的解决方案?

  • 好主意,但我不喜欢在添加后从列表中删除错误的想法.我宁愿不首先添加它们. (2认同)