Inherited = false对viewModel中的字段属性不起作用

时间:2013-12-26 17:15:32

标签: c# asp.net-mvc custom-attributes asp.net-mvc-viewmodel

我制作了测试属性

    [AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)]
    public class NonInheritedRequiredAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
                return new ValidationResult((validationContext.DisplayName));
            return null;
        }
    }

和viewModels

    public class ViewModelA
    {
        [NonInheritedRequired]
        public virtual string Property{ get; set; }
    }

    public class ViewModelB : ViewModelA
    {
        public override string Property{ get; set; }
    }

行动方法

        [HttpPost]
        public ActionResult Index(ViewModelB viewModel)
        {
            if (ModelState.IsValid)
            {
                return View("OtherView");
            }

            return View(viewModel);
        }

ModelState始终无效。在验证时,它使用NonInheritedRequired的验证,尽管它具有Inherited = false。 我该如何解决这个问题?

感谢。

1 个答案:

答案 0 :(得分:3)

MVC中不尊重Inherited属性。

可能的解决方案:

  1. 实施custom ModelValidatorProvider,过滤掉不可继承的验证属性。

  2. 通过提供自定义TypeDescriptionProvider

  3. 过滤掉不可继承的属性
  4. 在模型中使用MetadataType属性。这是最简单的。

  5. 样品

    [MetadataType(typeof(ModelAMetadata))]
    public class ModelA
    {
        public virtual string Property { get; set; }
    }
    
    public class ModelAMetadata
    {
        [Required]
        public string Property { get; set; }
    }
    
    [MetadataType(typeof(ModelBMetadata))]
    public class ModelB : ModelA
    {
        public override string Property { get; set; }
    }
    
    public class ModelBMetadata
    {
        //notice that there is no Required attribute here
        public string Property { get; set; }
    }
    

    最优雅的解决方案是#1,但我建议改为重新设计模型。