C# “的MVC3自定义验证属性”;“至少需要一个”;情况

C# “的MVC3自定义验证属性”;“至少需要一个”;情况,c#,asp.net-mvc-3,validation,C#,Asp.net Mvc 3,Validation,嗨,我已经找到了这个答案: 它相当特定于组名的检查,并使用反射 我的例子可能更简单一些,我只是想知道是否有更简单的方法 我有以下资料: public class TimeInMinutesViewModel { private const short MINUTES_OR_SECONDS_MULTIPLIER = 60; //public string Label { get; set; } [Range(0,24, ErrorMessage = "Hours s

嗨,我已经找到了这个答案:

它相当特定于组名的检查,并使用反射

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

我有以下资料:

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));
    }
}
公共类时间分钟视图模型{
私人常数短分钟或秒乘数=60;
//公共字符串标签{get;set;}
[范围(0,24,ErrorMessage=“小时数应为0到24”)]
公共短时间{get;set;}
[范围(0,59,ErrorMessage=“分钟应为0到59”)]
公共短分钟数{get;set;}
/// 
/// 
/// 
/// 
公共短时分钟(){
//总分钟数不应为负数

if(Hours您链接的示例通过将属性应用于属性来定义组,这提供了很大的灵活性。这种灵活性的代价是反射代码。灵活性较低的方法更容易实现,但适用范围更窄

对于这种方法,这里有一个有效的方法;我将把它留给您来适应另一个示例的其余部分:

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

您链接到的示例通过将属性应用于属性来定义组,这提供了很大的灵活性。这种灵活性的代价是反射代码。灵活性较低的方法更容易实现,但适用范围更窄

对于这种方法,这里有一个有效的方法;我将把它留给您来适应另一个示例的其余部分:

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

签出FluentValidation,或者您可以对每个要检查是否至少有一个属性具有值的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
}

注意。

请检查FluentValidation,或者您可以对每个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
}

问候。

您好,谢谢您的快速回复,我可以在这里的示例中询问您,我假设您使用了类的属性,因为这行:“var viewModel=value as TimeInMinutesViewModel”。如果仅将属性应用于每个属性,是否很难实现相同的目标?thanks@Pricey是的,这个答案假设属性应用于类。显然,这个属性只能应用于一个类。就像我说的,它是不灵活和狭窄的。要在两个属性上使用属性,你需要r必须使用基于反射的方法(坦白说,这就是我要做的)或者,假设您可以从
ValidationContext
中获得所需的信息,编写一个狭义专门化的属性来应用于属性。不幸的是,我对ValidationContext了解不够,无法知道这是否可行。您好,感谢您的快速回复,我可以在这里的示例中询问您是否使用了由于这一行,“var viewModel=作为TimeInMinutesViewModel的值”。如果仅将属性应用于每个属性,是否很难实现相同的目标?thanks@Pricey是的,这个答案假设属性应用于类。显然,这个属性只能应用于一个类。就像我说的,它是不灵活和狭窄的。要在两个属性上使用属性,你需要r必须使用基于反射的方法(坦白说,这就是我要做的)或者,假设您可以从
ValidationContext
中获得所需的信息,编写一个狭义专门化的属性来应用于属性。不幸的是,我对ValidationContext的了解不够,无法知道这是否可行。+1表示评估类上所有属性的示例。+1表示评估的示例正在初始化类上的所有属性。的可能重复项的可能重复项