在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现Model两个中两个属性值的比较验证

具体应用场景为:要对两个属性值的大小进行验证

代码如下所示:

    /// <summary>
/// Specifies that the field must compare favourably with the named field, if objects to check are not of the same type
/// false will be return
/// </summary>
public class CompareValuesAttribute : ValidationAttribute
{
/// <summary>
/// The other property to compare to
/// </summary>
public string OtherProperty { get; set; } public CompareValues Criteria { get; set; } /// <summary>
/// Creates the attribute
/// </summary>
/// <param name="otherProperty">The other property to compare to</param>
public CompareValuesAttribute(string otherProperty, CompareValues criteria)
{
if (otherProperty == null)
throw new ArgumentNullException("otherProperty"); OtherProperty = otherProperty;
Criteria = criteria;
} /// <summary>
/// Determines whether the specified value of the object is valid. For this to be the case, the objects must be of the same type
/// and satisfy the comparison criteria. Null values will return false in all cases except when both
/// objects are null. The objects will need to implement IComparable for the GreaterThan,LessThan,GreatThanOrEqualTo and LessThanOrEqualTo instances
/// </summary>
/// <param name="value">The value of the object to validate</param>
/// <param name="validationContext">The validation context</param>
/// <returns>A validation result if the object is invalid, null if the object is valid</returns>
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// the the other property
var property = validationContext.ObjectType.GetProperty(OtherProperty); // check it is not null
if (property == null)
return new ValidationResult(String.Format("Unknown property: {0}.", OtherProperty)); // check types
var memberName = validationContext.ObjectType.GetProperties().Where(p => p.GetCustomAttributes(false).OfType<DisplayAttribute>().Any(a => a.Name == validationContext.DisplayName)).Select(p => p.Name).FirstOrDefault();
if (memberName == null)
{
memberName = validationContext.DisplayName;
}
if (validationContext.ObjectType.GetProperty(memberName).PropertyType != property.PropertyType)
return new ValidationResult(String.Format("The types of {0} and {1} must be the same.", memberName, OtherProperty)); // get the other value
var other = property.GetValue(validationContext.ObjectInstance, null); // equals to comparison,
if (Criteria == CompareValues.EqualTo)
{
if (Object.Equals(value, other))
return null;
}
else if (Criteria == CompareValues.NotEqualTo)
{
if (!Object.Equals(value, other))
return null;
}
else
{
// check that both objects are IComparables
if (!(value is IComparable) || !(other is IComparable))
return new ValidationResult(String.Format("{0} and {1} must both implement IComparable", validationContext.DisplayName, OtherProperty)); // compare the objects
var result = Comparer.Default.Compare(value, other); switch (Criteria)
{
case CompareValues.GreaterThan:
if (result > )
return null;
break;
case CompareValues.LessThan:
if (result < )
return null;
break;
case CompareValues.GreatThanOrEqualTo:
if (result >= )
return null;
break;
case CompareValues.LessThanOrEqualTo:
if (result <= )
return null;
break;
}
} // got this far must mean the items don't meet the comparison criteria
return new ValidationResult(ErrorMessage);
}
} /// <summary>
/// Indicates a comparison criteria used by the CompareValues attribute
/// </summary>
public enum CompareValues
{
EqualTo,
NotEqualTo,
GreaterThan,
LessThan,
GreatThanOrEqualTo,
LessThanOrEqualTo
}

应用的时候直接在指定的属性上添加此CompareValuesAttribute标签即可

【注:第一个参数是要与之比较的属性名,第二个参数表示两个属性值之间的大小关系,第三个参数表示错误提示信息】

public class EricSunModel
{
[Display(Name = "Ready Time")]
public string ReadyTime { get; set; } [CompareValues("ReadyTime", CompareValues.GreaterThan, ErrorMessage = "Close time must be later than ready time")]
[Display(Name = "Close Time")]
public string CloseTime { get; set; } }

更多细节可以参考如下链接:

http://cncrrnt.com/blog/index.php/2011/01/custom-validationattribute-for-comparing-properties/

这里提供一个我自己的增强版本,可以添加另外一个依赖条件。

代码如下:

    public class CompareValuesAttribute : ValidationAttribute
{
/// <summary>
/// The other property to compare to
/// </summary>
public string OtherProperty { get; set; }
public CompareCriteria Criteria { get; set; } /// <summary>
/// The other dependent rule
/// </summary>
public string RulePropertyName { get; set; }
public CompareCriteria RuleCriteria { get; set; }
public object RulePropertyValue { get; set; } public bool CustomErrorMessage { get; set; } /// <summary>
/// Compare values with other property based on other rules or not
/// </summary>
/// <param name="otherProperty">other property.</param>
/// <param name="criteria">criteria</param>
/// <param name="rulePropertyName">rule property name. (if don't based on other rules, please input null)</param>
/// <param name="ruleCriteria">rule criteria. (if don't based on other rules, please input null)</param>
/// <param name="rulePropertyValue">rule property value. (if don't based on other rules, please input null)</param>
/// <param name="customErrorMessage">custom error message. (if don't need customize error message format, please input null)</param>
public CompareValuesAttribute(string otherProperty, CompareCriteria criteria, string rulePropertyName, CompareCriteria ruleCriteria, object rulePropertyValue, bool customErrorMessage)
{
OtherProperty = otherProperty;
Criteria = criteria;
RulePropertyName = rulePropertyName;
RuleCriteria = ruleCriteria;
RulePropertyValue = rulePropertyValue;
CustomErrorMessage = customErrorMessage;
} /// <summary>
/// Compare values with other property
/// </summary>
/// <param name="otherProperty"></param>
/// <param name="criteria"></param>
/// <param name="customErrorMessage"></param>
public CompareValuesAttribute(string otherProperty, CompareCriteria criteria, bool customErrorMessage)
{
OtherProperty = otherProperty;
Criteria = criteria;
RulePropertyName = null;
CustomErrorMessage = customErrorMessage;
} protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (ValidateDependentRule(validationContext) == null) //validate dependent rule successful
{
if (OtherProperty == null)
{
return new ValidationResult(String.Format("Orther property is null."));
} // the the other property
var property = validationContext.ObjectType.GetProperty(OtherProperty); // check it is not null
if (property == null)
{
return new ValidationResult(String.Format("Unknown property: {0}.", OtherProperty));
} // check types
var memberName = validationContext.ObjectType.GetProperties().Where(p => p.GetCustomAttributes(false).OfType<DisplayAttribute>().Any(a => a.Name == validationContext.DisplayName)).Select(p => p.Name).FirstOrDefault();
if (memberName == null)
{
memberName = validationContext.DisplayName;
}
if (validationContext.ObjectType.GetProperty(memberName).PropertyType != property.PropertyType)
{
return new ValidationResult(String.Format("The types of {0} and {1} must be the same.", memberName, OtherProperty));
} // get the other value
var other = property.GetValue(validationContext.ObjectInstance, null); if (CompareValues(value, other, Criteria, validationContext) == null)
{
return null;
}
else
{
// got this far must mean the items don't meet the comparison criteria
if (CustomErrorMessage)
{
return new ValidationResult(string.Format(ErrorMessage, other));
}
else
{
return new ValidationResult(ErrorMessage);
}
}
}
else
{
return null; //dependent rule isn't exist or validate dependent rule failed
}
} private ValidationResult ValidateDependentRule(ValidationContext validationContext)
{
ValidationResult validateRuleResult = null; // has dependent rule
if (RulePropertyName != null)
{
var rulePropertyName = validationContext.ObjectType.GetProperty(RulePropertyName);
if (rulePropertyName == null)
return new ValidationResult(String.Format("Unknown rule property name: {0}.", RulePropertyName)); var rulePropertyRealValue = rulePropertyName.GetValue(validationContext.ObjectInstance, null); validateRuleResult = CompareValues(rulePropertyRealValue, RulePropertyValue, RuleCriteria, validationContext);
} return validateRuleResult;
} private ValidationResult CompareValues(object targetValue, object otherValue, CompareCriteria compareCriteria, ValidationContext validationContext)
{
ValidationResult compareResult = new ValidationResult("Compare Values Failed."); // equals to comparison,
if (compareCriteria == CompareCriteria.EqualTo)
{
if (Object.Equals(targetValue, otherValue)) compareResult = null;
}
else if (compareCriteria == CompareCriteria.NotEqualTo)
{
if (!Object.Equals(targetValue, otherValue)) compareResult = null;
}
else
{
// check that both objects are IComparables
if (!(targetValue is IComparable) || !(otherValue is IComparable))
compareResult = new ValidationResult(String.Format("{0} and {1} must both implement IComparable", validationContext.DisplayName, OtherProperty)); // compare the objects
var result = Comparer.Default.Compare(targetValue, otherValue); switch (compareCriteria)
{
case CompareCriteria.GreaterThan:
if (result > ) compareResult = null;
break;
case CompareCriteria.LessThan:
if (result < ) compareResult = null;
break;
case CompareCriteria.GreatThanOrEqualTo:
if (result >= ) compareResult = null;
break;
case CompareCriteria.LessThanOrEqualTo:
if (result <= ) compareResult = null;
break;
}
} return compareResult;
}
} public enum CompareCriteria
{
EqualTo,
NotEqualTo,
GreaterThan,
LessThan,
GreatThanOrEqualTo,
LessThanOrEqualTo
}

在Asp.Net MVC中实现CompareValues标签对Model中的属性进行验证的更多相关文章

  1. CompareValues标签对Model中的属性进行验证

    在Asp.Net MVC中实现CompareValues标签对Model中的属性进行验证   在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现Model两个 ...

  2. 在Asp.Net MVC中实现RequiredIf标签对Model中的属性进行验证

    在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现RequiredIf标签对Model中的属性进行验证 具体场景为:某一属性是否允许为null的验证,要根据另 ...

  3. 在.Net MVC中自定义ValidationAttribute标签对Model中的属性做验证

    写一个继承与ValidationAttribute类的自定义的验证方法 MVC中传递数据时,大多数都会用Model承载数据,并且在传到控制器后,对Model进行一系列的验证. 我平时经常使用的判断方法 ...

  4. Asp.net mvc + .net ef database first 或 model first 时如何添加验证特性

    今天有个同事问到,在使用Entity Framework 的Database frist或model first时,怎么在model上添加验证的特性? 因为此时的Model是是VS 工具怎么生成的,直 ...

  5. 返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model

    原文:返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model [索引页][源码下载] 返璞归真 asp.net mvc (8) - asp.net mvc ...

  6. mvc中动态给一个Model类的属性设置验证

    原文:mvc中动态给一个Model类的属性设置验证 在mvc中有自带的验证机制,比如如果某个字段的类型是数字或者日期,那么用户在输入汉字或者英文字符时,那么编译器会自动验证并提示用户格式不正确,不过这 ...

  7. 总结ASP.NET MVC Web Application中将数据显示到View中的几种方式

    当我们用ASP.NET MVC开发Web应用程序的时候,我们都是将需要呈现的数据通过"Controllers"传输到"View"当中,怎么去实现,下面我介绍一下 ...

  8. Asp.Net MVC 从客户端<a href="http://www....")中检测到有潜在危险的 Request.Form 值

    Asp.Net MVC应用程序, Framework4.0: 则需要在webconfig文件的 <system.web> 配置节中加上 <httpRuntime requestVal ...

  9. asp.net mvc 3.0 知识点整理 ----- (2).Controller中几种Action返回类型对比

    通过学习,我们可以发现,在Controller中提供了很多不同的Action返回类型.那么具体他们是有什么作用呢?它们的用法和区别是什么呢?通过资料书上的介绍和网上资料的查询,这里就来给大家列举和大致 ...

随机推荐

  1. [转载]Python 3.5 协程究竟是个啥

    http://blog.rainy.im/2016/03/10/how-the-heck-does-async-await-work-in-python-3-5/ [译] Python 3.5 协程究 ...

  2. POJ 1065

    http://poj.org/problem?id=1065 题目的大体意思就是给一些木头长l,重w,有一个机器,如果切割这些木头的话,在i后面切割的i+1根木头满足长度和重量都要大于等于前一根则不需 ...

  3. struts2 初步总结

    1.Struts2的概述: 2.Struts2的入门: * 2.1下载struts2的zip包. * 2.2创建web工程. * 2.3配置... 3.Struts2的开发流程: * 3.1流程: * ...

  4. linux资源使用配置文件 /etc/security/limits.conf和ulimit

    limits.conf文件实际上是linux PAM中pam_limits.so的配置文件,而且只针对于单个会话. limits.conf的格式如下: <domain> <type& ...

  5. 自动化运维工具ansible学习+使用ansible批量推送公钥到远程主机

    目录: 一.ansible简介 1.1.ansible是什么 1.2.ansible如何工作 1.3.ansible优缺点 1.4.ansible安装方式 1.5.ansible文件简单介绍 1.6. ...

  6. nyoj17_又做最大递增子序列

    单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 求一个字符串的最长递增子序列的长度 如:dabdbf最长递增子序列就是abdf,长度为4   输入 ...

  7. pom.xml中引入局域网仓库

    <repositories> <repository> <id>nexus</id> <name>my-nexus-repository&l ...

  8. WCF服务与WCF数据服务的区别

    问: Hi, I am newbie to wcf programming and a little bit confused between WCF Service and WCF Data  Se ...

  9. IOS - Passbook

    1. 什么是Passbook Passbook是苹果公司于北京时间2012年6月12日上午,在全球开发者大会(WWDC)上宣布了iOS 6系统将提供操作一个全新的应用——Passbook 这是一款可以 ...

  10. Sqlserver 创建到sqlserver 的链接服务器

    exec sp_addlinkedserver 'SN_MASTER_SRV', '', 'SQLOLEDB ', '129.223.252.173' exec sp_addlinkedsrvlogi ...