123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Globalization;
- using System.ComponentModel;
- using System.ComponentModel.DataAnnotations;
- using System.Web.Mvc;
- namespace Bowin.Common.Mvc
- {
- [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
- public class RangeIfIdsInAttribute : ValidationAttribute, IClientValidatable
- {
- private const string DefaultErrorMessage = "字段 {0} 必须在 {1} 和 {2} 之间。";
- private const string Template = "$-{0}-$";
- private RangeIfIdsInAttribute(string otherProperty, string[] ids)
- : base(DefaultErrorMessage)
- {
- if (string.IsNullOrEmpty(otherProperty))
- {
- throw new ArgumentNullException("otherProperty");
- }
- if (ids == null || ids.Length == 0)
- {
- throw new ArgumentNullException("ids");
- }
- OtherProperty = otherProperty;
- StringBuilder sb = new StringBuilder();
- foreach (var item in ids)
- {
- sb.AppendFormat(string.Format("{0},", Template), item);
- }
- Ids = sb.ToString().TrimEnd(',').ToLower();
- }
- public RangeIfIdsInAttribute(int minimum, int maximum, string otherProperty, string[] ids)
- : this(otherProperty, ids)
- {
- this.Minimum = minimum;
- this.Maximum = maximum;
- this.OperandType = typeof(int);
- }
- public RangeIfIdsInAttribute(double minimum, double maximum, string otherProperty, string[] ids)
- : this(otherProperty, ids)
- {
- this.Minimum = minimum;
- this.Maximum = maximum;
- this.OperandType = typeof(double);
- }
- public string OtherProperty { get; private set; }
- public object Minimum { get; private set; }
- public object Maximum { get; private set; }
- public string Ids { get; private set; }
- public Type OperandType { get; private set; }
- private Func<object, object> Conversion { get; set; }
- public static string FormatPropertyForClientValidation(string property)
- {
- if (property == null)
- {
- throw new ArgumentException("属性值不能为空!", "property");
- }
- return ("*." + property);
- }
- public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
- {
- var clientValidationRule = new ModelClientValidationRule()
- {
- ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
- ValidationType = "rangeifidsin"
- };
- clientValidationRule.ValidationParameters.Add("otherproperty", FormatPropertyForClientValidation(OtherProperty));
- clientValidationRule.ValidationParameters.Add("ids", Ids);
- clientValidationRule.ValidationParameters.Add("minimum", Minimum);
- clientValidationRule.ValidationParameters.Add("maximum", Maximum);
- clientValidationRule.ValidationParameters.Add("template", Template);
- return new[] { clientValidationRule };
- }
- public override string FormatErrorMessage(string name)
- {
- this.SetupConversion();
- return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, new object[] { name, Minimum, Maximum });
- }
- protected override ValidationResult IsValid(object value, ValidationContext validationContext)
- {
- if (value == null) return ValidationResult.Success;
- this.SetupConversion();
- var otherProperty = validationContext.ObjectInstance.GetType().GetProperty(OtherProperty);
- var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
- if (otherPropertyValue == null) return ValidationResult.Success;
- var otherPropertyLowerValue = otherPropertyValue.ToString().ToLower();
- if (!Ids.Contains(otherPropertyLowerValue)) return ValidationResult.Success;
- object obj2 = null;
- try
- {
- obj2 = this.Conversion(value);
- }
- catch (FormatException)
- {
- return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
- }
- catch (InvalidCastException)
- {
- return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
- }
- catch (NotSupportedException)
- {
- return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
- }
- IComparable minimum = (IComparable)this.Minimum;
- IComparable maximum = (IComparable)this.Maximum;
- if ((minimum.CompareTo(obj2) <= 0) && (maximum.CompareTo(obj2) >= 0))
- {
- return ValidationResult.Success;
- }
- else
- {
- return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
- }
- }
- private void SetupConversion()
- {
- if (this.Conversion == null)
- {
- object minimum = this.Minimum;
- object maximum = this.Maximum;
- if ((minimum == null) || (maximum == null))
- {
- throw new InvalidOperationException("必须设置最大值和最小值。");
- }
- Type type = minimum.GetType();
- if (type == typeof(int))
- {
- this.Initialize((int)minimum, (int)maximum, v => Convert.ToInt32(v, CultureInfo.InvariantCulture));
- }
- else if (type == typeof(double))
- {
- this.Initialize((double)minimum, (double)maximum, v => Convert.ToDouble(v, CultureInfo.InvariantCulture));
- }
- else
- {
- type = this.OperandType;
- if (type == null)
- {
- throw new InvalidOperationException("必须设置操作类型。");
- }
- Type type2 = typeof(IComparable);
- if (!type2.IsAssignableFrom(type))
- {
- throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "类型 {0} 和类型 {1} 不支持比较运算。", new object[] { type.FullName, type2.FullName }));
- }
- TypeConverter converter = TypeDescriptor.GetConverter(type);
- IComparable comparable = (IComparable)converter.ConvertFromString((string)minimum);
- IComparable comparable2 = (IComparable)converter.ConvertFromString((string)maximum);
- Func<object, object> conversion = delegate(object value)
- {
- if ((value != null) && (value.GetType() == type))
- {
- return value;
- }
- return converter.ConvertFrom(value);
- };
- this.Initialize(comparable, comparable2, conversion);
- }
- }
- }
- private void Initialize(IComparable minimum, IComparable maximum, Func<object, object> conversion)
- {
- if (minimum.CompareTo(maximum) > 0)
- {
- throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "最小值 {0} 必须小于最大值 {1} 。", new object[] { maximum, minimum }));
- }
- this.Minimum = minimum;
- this.Maximum = maximum;
- this.Conversion = conversion;
- }
- }
- }
|