C# MVC 验证低于/高于其他值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18577777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVC Validation Lower/Higher than other value
提问by Ben Ford
How is the best way to validate a model in MVC.Net where I want to accept a minimum/maximum.
在 MVC.Net 中验证模型的最佳方法是如何接受最小值/最大值。
Not individual min/max values for a field. But separate fields for a user to specify a minimum/maximum.
不是单个字段的最小/最大值。但是单独的字段供用户指定最小值/最大值。
public class FinanceModel{
public int MinimumCost {get;set;}
public int MaximumCost {get;set;}
}
So I need to ensure that MinimumCost is always less than Maximum cost.
所以我需要确保最小成本总是小于最大成本。
采纳答案by Boranas
You can use a custom validation attribute here is my example with dates. But you can use it with ints too.
您可以在此处使用自定义验证属性,这是我的日期示例。但是您也可以将它与整数一起使用。
First, here is the model :
首先,这是模型:
public DateTime Beggining { get; set; }
[IsDateAfterAttribute("Beggining", true, ErrorMessageResourceType = typeof(LocalizationHelper), ErrorMessageResourceName = "PeriodErrorMessage")]
public DateTime End { get; set; }
And here is the attribute itself :
这是属性本身:
public sealed class IsDateAfterAttribute : ValidationAttribute, IClientValidatable
{
private readonly string testedPropertyName;
private readonly bool allowEqualDates;
public IsDateAfterAttribute(string testedPropertyName, bool allowEqualDates = false)
{
this.testedPropertyName = testedPropertyName;
this.allowEqualDates = allowEqualDates;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.testedPropertyName);
if (propertyTestedInfo == null)
{
return new ValidationResult(string.Format("unknown property {0}", this.testedPropertyName));
}
var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);
if (value == null || !(value is DateTime))
{
return ValidationResult.Success;
}
if (propertyTestedValue == null || !(propertyTestedValue is DateTime))
{
return ValidationResult.Success;
}
// Compare values
if ((DateTime)value >= (DateTime)propertyTestedValue)
{
if (this.allowEqualDates && value == propertyTestedValue)
{
return ValidationResult.Success;
}
else if ((DateTime)value > (DateTime)propertyTestedValue)
{
return ValidationResult.Success;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessageString,
ValidationType = "isdateafter"
};
rule.ValidationParameters["propertytested"] = this.testedPropertyName;
rule.ValidationParameters["allowequaldates"] = this.allowEqualDates;
yield return rule;
}
回答by Matthew
There is a NuGet package called Foolproofwhich provides these annotations for you. That said - writing a custom attribute is both pretty easy and good practice.
有一个名为Foolproof的 NuGet 包可以为您提供这些注释。也就是说 - 编写自定义属性既非常简单又很好。
Using Foolproof would look like:
使用万无一失看起来像:
public class FinanceModel{
public int MinimumCost {get;set;}
[GreaterThan("MinimumCost")]
public int MaximumCost {get;set;}
}
回答by Khalid
Why you are not used Range Validator. Syntax:
为什么不使用 Range Validator。句法:
[Range(typeof(int), "0", "100", ErrorMessage = "{0} can only be between {1} and {2}")]
public int Percentage { get; set; }
回答by Nicolas Galler
For client side validation using the allowEqualDates and propertyTested parameters (complement to Boranas answer above but too long for comment):
对于使用 allowEqualDates 和 propertyTested 参数的客户端验证(对上面 Boranas 回答的补充,但评论太长):
// definition for the isdateafter validation rule
if ($.validator && $.validator.unobtrusive) {
$.validator.addMethod('isdateafter', function (value, element, params) {
value = Date.parse(value);
var otherDate = Date.parse($(params.compareTo).val());
if (isNaN(value) || isNaN(otherDate))
return true;
return value > otherDate || (value == otherDate && params.allowEqualDates);
});
$.validator.unobtrusive.adapters.add('isdateafter', ['propertytested', 'allowequaldates'], function (options) {
options.rules['isdateafter'] = {
'allowEqualDates': options.params['allowequaldates'],
'compareTo': '#' + options.params['propertytested']
};
options.messages['isdateafter'] = options.message;
});
}
More information: unobtrusive validation, jquery validation
回答by Dani
In VB for integers:
在 VB 中,整数:
MODEL
模型
<UtilController.IsIntegerGreatherOrEqualThan("PropertyNameNumberBegins", "PeriodErrorMessage")>
Public Property PropertyNameNumberEnds As Nullable(Of Integer)
VALIDATION
验证
Public Class IsIntegerGreatherOrEqualThan
Inherits ValidationAttribute
Private otherPropertyName As String
Private errorMessage As String
Public Sub New(ByVal otherPropertyName As String, ByVal errorMessage As String)
Me.otherPropertyName = otherPropertyName
Me.errorMessage = errorMessage
End Sub
Protected Overrides Function IsValid(thisPropertyValue As Object, validationContext As ValidationContext) As ValidationResult
Dim otherPropertyTestedInfo = validationContext.ObjectType.GetProperty(Me.otherPropertyName)
If (otherPropertyTestedInfo Is Nothing) Then
Return New ValidationResult(String.Format("unknown property {0}", Me.otherPropertyName))
End If
Dim otherPropertyTestedValue = otherPropertyTestedInfo.GetValue(validationContext.ObjectInstance, Nothing)
If (thisPropertyValue Is Nothing) Then
Return ValidationResult.Success
End If
'' Compare values
If (CType(thisPropertyValue, Integer) >= CType(otherPropertyTestedValue, Integer)) Then
Return ValidationResult.Success
End If
'' Wrong
Return New ValidationResult(errorMessage)
End Function
End Class