我如何在DataAnnotations中使用DRY(不要自己重复)错误消息来自Resourse

时间:2017-04-23 09:51:22

标签: c# asp.net-mvc data-annotations

这是我的代码

    [Required(ErrorMessageResourceType = typeof(DCC.RegistrationVMLiterals), ErrorMessageResourceName = "Required")]
    [RegularExpression("^[0-9]*$", ErrorMessageResourceType =typeof(DCC.RegistrationVMLiterals),ErrorMessageResourceName ="MustBeNumber")]
    [Display(Name = "BeneficiaryNo")]
    public long BeneficiaryNo { get; set; }

    [Required(ErrorMessageResourceType = typeof(DCC.RegistrationVMLiterals), ErrorMessageResourceName = "Required")]
    [RegularExpression("^[a-zA-z]*$",ErrorMessage ="must only be letters")]
    [Display(Name = "FullName")]
    public string FullName { get; set; }
    [Required(ErrorMessageResourceType = typeof(DCC.RegistrationVMLiterals), ErrorMessageResourceName = "Required")]
    [Display(Name = "GenderID")]
    public int GenderID { get; set; }`

2 个答案:

答案 0 :(得分:0)

试试这个,没有经过测试,但这应该有效:

[AttributeUsage(AttributeTargets.Class)]
public class AggregatedRequiredAttribute: ValidationAttribute
{
    private readonly string[] _propertiesToValidate;
    private readonly string message = Resources.ValRequired;

    public AggregatedRequiredAttribute(params string[] propertiesToValidate)
    {
        if (propertiesToValidate == null || !propertiesToValidate.Any()) throw new ArgumentException(nameof(propertiesToValidate));
        _propertiesToValidate = propertiesToValidate;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (!validationContext.ObjectType.GetMember(validationContext.MemberName).Any())
            throw new InvalidOperationException("Current type does not contain such property.");

        if (!_propertiesToValidate.Contains(validationContext.MemberName))
            return ValidationResult.Success;

        var defaultRequired = new RequiredAttribute() {ErrorMessage = message};
        return defaultRequired.IsValid(value) ? ValidationResult.Success : new ValidationResult(message);
    }
}

然后你可以像这样使用它(来自默认MVC模板的ViewModel):

[AggregatedRequired("Email","Password")]
public class RegisterViewModel
{
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

注意,我只使用了一次错误消息字符串,也可以在错误消息中使用一些字母并将其动态替换为要验证的属性的实际名称。

更新

我不确定第一个if声明,你应该测试一下。

更新2

此外我猜我使用了错误的IsValid方法,但想法本身很清楚。

答案 1 :(得分:0)

我认为你误解了这个概念或DRY。

你重复的事实

ngOnInit() {
     this.PcOrMobile();
     App.init();
     App.initScrollBar();
     App.initParallaxBg();
     OwlCarousel.initOwlCarousel();
     RevolutionSlider.initRSfullWidth();
     StyleSwitcher.initStyleSwitcher();
     MasterSliderShowcase2.initMasterSliderShowcase2();
     this.getHomepage();
     this.getWantedList(1,6);
     this.bannerAnimation();
 }

在这种情况下不是重复。

重复会是这样的:

[Required(ErrorMessageResourceType = typeof(DCC.RegistrationVMLiterals), ErrorMessageResourceName = "Required")]
[RegularExpression("^[0-9]*$", ErrorMessageResourceType =typeof(DCC.RegistrationVMLiterals),ErrorMessageResourceName ="MustBeNumber")]

DRY对此的回应是

public void DoSomething()
{
    string myString = "ABC";
    Print(myString);
    Do something...
}

public void DoSomething1()
{
    string myString = "ABC";
    Print(myString);
    Do something different...
}