代码之家  ›  专栏  ›  技术社区  ›  Jeff

如何支持模型属性的条件验证

  •  1
  • Jeff  · 技术社区  · 15 年前

    我目前有一个表格,我正在建设,需要支持两个不同的版本。每个版本可能使用不同的表单域子集。我必须这样做才能支持两个不同的客户机,但我不想对这两个客户机都有完全不同的控制器操作。

    因此,我试图想出一种方法,使用带有验证属性的强类型模型,但其中一些属性是有条件的。

    我能想到的一些方法类似于史蒂夫·桑德森的 partial validation 方法。

    在这里,我将清除基于表单的哪个版本处于活动状态的actionexecuting筛选器中的模型错误。

    我想到的另一种方法是用类似于

    class FormModel
    {
    
    public Form1 Form1Model {get; set;}
    public Form2 FormModel {get; set;}
    }
    

    然后根据版本找到一些方法来验证适当的属性。模型上也会有一些共同的属性,它们都会被验证。

    有人对此有好的建议吗?

    1 回复  |  直到 15 年前
        1
  •  3
  •   Simon_Weaver    15 年前

    在使用modelbinder从modelstate中删除不需要的错误方面,我已经取得了合理的成功。

    下面是一个 Address 模型活页夹。在用户界面中,我有一个 <SELECT> 对美国各州来说,但当这个国家不是“我们”而支持 <INPUT ID=StateOrProvince> 文本框。

    modelbinder查看国家并删除不需要的值。

    就验证属性而言,除非你有非常简单的规则,否则你会很快陷入一个大混乱。

    提示: 您可以拥有尽可能多的modelbinder来离散整个模型的各个部分。例如-我有两个 地址 我的模型中的对象和它们各自自动应用此行为。

    注册:

    ModelBinders.Binders[typeof(UI.Address)] = new AddressModelBinder();
    

    ModelBinder:

    public class AddressModelBinder : DefaultModelBinder
    {
        protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            base.OnModelUpdated(controllerContext, bindingContext);
    
            // get the address to validate
            var address = (Address)bindingContext.Model;
    
            // remove statecd for non-us
            if (address.IsUSA)
            {
                address.StateOrProvince = string.IsNullOrEmpty(address.StateCd) ? null : CountryCache.GetStateName(address.StateCd);
                bindingContext.ModelState.Remove(bindingContext.ModelName + ".StateOrProvince");
            }
            else
            {
                address.StateCd = null;
                bindingContext.ModelState.Remove(bindingContext.ModelName + ".StateCd");
            }
    
    
            // validate US zipcode
            if (address.CountryCode == "US")
            {
                if (new Regex(@"^\d{5}([\-]\d{4})?$", RegexOptions.Compiled).Match(address.ZipOrPostal ?? "").Success == false)
                {
                    bindingContext.ModelState.AddModelError(bindingContext.ModelName + ".ZipOrPostal", "The value " + address.ZipOrPostal + " is not a valid zipcode");
                }
            }
    
            // all other modelbinding attributes such as [Required] will be processed as normal
        }
    }