【问题标题】:MVC3 custom validation attribute for an "at least one is required" situation“至少需要一个”情况的 MVC3 自定义验证属性
【发布时间】:2012-04-14 16:48:57
【问题描述】:

您好,我已经找到了这个答案: 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));
    }
}

我想向 Hours & Minutes 属性或类本身添加一个验证属性。其想法是确保这些属性中的至少 1 个(小时或分钟)具有值,服务器端和客户端使用自定义验证属性进行验证。

请问有人有这方面的例子吗?

谢谢

【问题讨论】:

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


【解决方案1】:

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

【讨论】:

  • 您好,感谢您的快速回复,我可以问一下,在您的示例中,由于这一行,我假设您在类上使用属性:“var viewModel = value as TimeInMinutesViewModel”。仅将属性应用于每个属性时,是否难以实现相同的目标?谢谢
  • @Pricey 是的,这个答案假设该属性应用于类。显然,这个属性只能应用于 one 类。就像我说的,它是僵化和狭窄的。要使用两个属性的属性执行此操作,您要么必须使用基于反射的方法(坦率地说,这是我会做的),要么假设您可以从 ValidationContext 获得所需的信息,请写应用于属性的狭义属性。不幸的是,我对 ValidationContext 了解不够,无法知道这是否可行。
猜你喜欢
  • 2018-07-11
  • 2011-07-21
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 2021-08-02
相关资源
最近更新 更多