MVC3自定义验证属性为“至少一个是必需的”情况

时间:2012-04-14 16:48:57

标签: c# asp.net-mvc-3 validation

您好我已经找到了这个答案: MVC3 Validation - Require One From Group

这对于检查组名并使用反射非常具体。

我的例子可能有点简单,我只是想知道是否有更简单的方法。

我有以下内容:

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));
    }
}

我想在“小时”和“时间”中添加验证属性。分钟属性或类本身..并且想法是确保使用自定义验证属性至少有一个属性(小时或分钟)具有值,服务器和客户端验证。

有人有这方面的例子吗?

由于

2 个答案:

答案 0 :(得分:5)

查看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;
    }
}

并将其应用于您的ViewModel:

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

问候。

答案 1 :(得分:2)

您链接的示例通过将属性应用于属性来定义组,这提供了很大的灵活性。这种灵活性的代价是反射代码。一种不太灵活的方法实施起来会更简单,但它的适用范围会更为狭窄。

这是一种用于这种方法的IsValid方法;我会留给你修改其他例子的其余部分:

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)); 
}