简体   繁体   English

针对“至少需要一个”情况的MVC3自定义验证属性

[英]MVC3 custom validation attribute for an “at least one is required” situation

Hi I have found this answer already: MVC3 Validation - Require One From Group 嗨,我已经找到了这个答案: MVC3验证-需要组中的一个

Which is fairly specific to the checking of group names and uses reflection. 这对于检查组名非常特定,并使用反射。

My example is probably a bit simpler and I was just wondering if there was a simpler way to do it. 我的示例可能更简单,我只是想知道是否有更简单的方法可以做到这一点。

I have the below: 我有以下内容:

public class TimeInMinutesViewModel {

    private const short MINUTES_OR_SECONDS_MULTIPLIER = 60;

    //public string Label { get; set; }

    [Range(0,24, ErrorMessage = "Hours should be from 0 to 24")]
    public short Hours { get; set; }

    [Range(0,59, ErrorMessage = "Minutes should be from 0 to 59")]
    public short Minutes { get; set; }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public short TimeInMinutes() {
        // total minutes should not be negative
        if (Hours <= 0 && Minutes <= 0) {
            return 0;
        }
        // multiplier operater treats the right hand side as an int not a short int 
        // so I am casting the result to a short even though both properties are already short int
        return (short)((Hours * MINUTES_OR_SECONDS_MULTIPLIER) + (Minutes * MINUTES_OR_SECONDS_MULTIPLIER));
    }
}

I want to add a validation attribute either to the Hours & Minutes properties or the class itself.. and the idea is to just make sure at least 1 of these properties (Hours OR minutes) has a value, server and client side validation using a custom validation attribute. 我想将验证属性添加到Hours&Minutes属性或类本身。.的想法是确保至少这些属性中的1个(小时或分钟)具有值,并使用a验证服务器和客户端自定义验证属性。

Does anyone have an example of this please? 请问有人有这个例子吗?

Thanks 谢谢

Check out FluentValidation http://fluentvalidation.codeplex.com/ or you can use this little helper for every ViewModel you wanna check if at least one property has value, or modify it further for your needs. 请访问FluentValidation http://fluentvalidation.codeplex.com/,或者为每个要查看至少一个属性是否有价值的ViewModel都可以使用此小助手,也可以根据需要对其进行进一步修改。

public class OnePropertySpecifiedAttribute : ValidationAttribute
{       
    public override bool IsValid(object value)
    {            
         Type typeInfo = value.GetType();
         PropertyInfo[] propertyInfo = typeInfo.GetProperties();
         foreach (var property in propertyInfo)
         {
            if (null != property.GetValue(value, null))
            {                    
               return true;
            }
         }           
         return false;
    }
}

And apply it on your ViewModel: 并将其应用于您的ViewModel:

[OnePropertySpecified(ErrorMessage="Either Hours or Minutes must be specified.")]
public class TimeInMinutesViewModel 
{
  //your code
}

Regards. 问候。

The example you linked to defines the group by applying attributes to the properties, which gives a lot of flexibility. 您链接到的示例通过将属性应用于属性来定义组,这提供了很大的灵活性。 The cost of that flexibility is the reflection code. 这种灵活性的代价就是反射代码。 A less flexible approach would be simpler to implement, but it would be more narrowly applicable. 较不灵活的方法将更易于实现,但适用范围更窄。

Here's an IsValid method for such an approach; 这是用于这种方法的IsValid方法; I'll leave it to you to adapt the rest of the other example: 我将它留给您以适应其他示例的其余部分:

protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
{
    var viewModel = value as TimeInMinutesViewModel;
    if (viewModel == null)
    {
        //I don't know whether you need to handle this case, maybe just...
        return null;
    }

    if (viewModel.Hours != 0 || viewModel.Minutes != 0)
        return null;

    return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM