标签:modify 格式不正确 help public sum ann hone email rate
mvc 实体类验证的时候 如果有多个验证特性需要在属性上层叠很多个验证特性,显得属性特别臃肿并且也不够直观,极大地影响我使用它的兴趣,所以我想自定义一个验证特性,然后将所有需要验证的情形全部放在一个特性里,看上去更直观一点。
[DataContract]
public partial class Sys_Menu : BaseModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[DataMember]
public int? MenuID { get; set; }
[Validate(DisplayName = "菜单URL", MaxLength = 100)]
[DataMember]
public string URL { get; set; }
[Validate(DisplayName = "菜单名", Required = true, MaxLength = 20)]
[DataMember]
public string Name { get; set; }
[StringLength(100)]
public string Description { get; set; }
[DataMember]
public int? ParentID { get; set; }
public bool? IsActive { get; set; }
自定义的验证特性是不是看上去更清爽一点
实现
public class ValidateAttribute : ValidationAttribute, IClientValidatable
{
private const string EmailPattern = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
private const string FixedPhonePattern = @"^(\d{3,4}-)?\d{6,8}$";
private const string MobilePhonePattern = @"^1\d{10}$";
///
/// 是否必填项
///
public bool Required { get; set; }
///
/// 数据格式
///
public FieldDataType DataType { get; set; }
///
/// 展示名称
///
public string DisplayName { get; set; }
///
/// 正则表达式
///
public string RegexPattern { get; set; }
public int MaxLength { get; set; }
public int MinLength { get; set; }
///
/// 验证
///
///
///
///
private bool IsMatch(string value, string regx)
{
if (string.IsNullOrEmpty(value))
{
return false;
}
bool isMatch = Regex.IsMatch(value, regx);
return isMatch;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (string.IsNullOrEmpty(DisplayName))
{
DisplayName = validationContext.MemberName;
}
//前后有空格
if (value is string && !value.Equals(value.ToString().Trim().ToString()))
{
IPropertyAccessor propertyAccessor = Caches.PropertyAccessorCache.Get(validationContext.ObjectType.GetProperty(validationContext.MemberName));
if (propertyAccessor != null)
{
propertyAccessor.SetValue(validationContext.ObjectInstance, value.ToString().Trim().ToString());
value = value.ToString().Trim().ToString();
}
}
ValidateResult result = Valid(value);
if (!result.IsValid)
{
return new ValidationResult(result.ErrorMessage);
}
else
{
return ValidationResult.Success;
}
}
///
/// 验证 如果不是必填项 只要不为空的才验证 待扩展
///
///
///
public ValidateResult Valid(object value)
{
if (this.Required)
{
if (value == null)
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "不能为空" };
}
if (value is string)
{
if (string.Empty.Equals(value.ToString()))
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "不能为空" };
}
}
else if (value is ICollection)
{
if (((ICollection)value).Count == 0)
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "条目不能为空" };
}
}
}
if (value != null)
{
switch (DataType)
{
case FieldDataType.Email:
if (!string.IsNullOrEmpty(value.ToString()) && !IsMatch(value.ToString(), EmailPattern))
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "不满足邮箱格式" };
}
break;
case FieldDataType.FixedPhone:
if (!string.IsNullOrEmpty(value.ToString()) && !IsMatch(value.ToString(), FixedPhonePattern))
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "不满足固话格式" };
}
break;
case FieldDataType.MobilePhone:
if (!string.IsNullOrEmpty(value.ToString()) && !IsMatch(value.ToString(), MobilePhonePattern))
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "不满足手机格式" };
}
break;
case FieldDataType.Phone:
if (!string.IsNullOrEmpty(value.ToString()) && (!IsMatch(value.ToString(), MobilePhonePattern) || !IsMatch(value.ToString(), FixedPhonePattern)))
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "不满足电话格式" };
}
break;
}
if (!string.IsNullOrEmpty(RegexPattern))
{
if (!string.IsNullOrEmpty(value.ToString()) && !IsMatch(value.ToString(), RegexPattern))
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "格式不正确" };
}
}
if (MaxLength != 0)
{
if (value is string)
{
if (!string.IsNullOrEmpty(value.ToString()) && value.ToString().Length > MaxLength)
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "超出数据最大长度" };
}
}
else if (value is ICollection)
{
if (((ICollection)value).Count > MaxLength)
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "超出最大条目" };
}
}
}
if (MinLength != 0)
{
if (value is string)
{
if (!string.IsNullOrEmpty(value.ToString()) && value.ToString().Length MinLength)
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "超出数据最小长度" };
}
}
else if (value is ICollection)
{
if (((ICollection)value).Count MinLength)
{
return new ValidateResult { IsValid = false, ErrorMessage = DisplayName + "超出最小条目" };
}
}
}
}
return new ValidateResult { IsValid = true, ErrorMessage = DisplayName + "验证通过" };
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
if (this.Required)
{
sb.Append("Required");
}
if (DataType != FieldDataType.None)
{
sb.Append(" DataType:" + DataType.ToString());
}
if (!string.IsNullOrEmpty(RegexPattern))
{
sb.Append(" RegexPattern:" + RegexPattern.ToString());
}
if (MaxLength != 0)
{
sb.Append(" MaxLength:" + MaxLength.ToString());
}
if (MinLength != 0)
{
sb.Append(" MinLength:" + MinLength.ToString());
}
return sb.ToString();
}
public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
throw new NotImplementedException();
}
}
可以根据自己的想法去验证
最后说说为什么要重写一个ToString(),这个是给HelpPage 接口说明文档使用的 我们将这个特性扩展进去,接口文档里开发人员就可以看到验证的说明
public class ModelDescriptionGenerator
{
// Modify this to support more data annotation attributes.
private readonly IDictionaryobject, string>> AnnotationTextGenerator = new Dictionaryobject, string>>
{
{ typeof(RequiredAttribute), a => "Required" },
{ typeof(RangeAttribute), a =>
{
RangeAttribute range = (RangeAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Range: inclusive between {0} and {1}", range.Minimum, range.Maximum);
}
},
{ typeof(MaxLengthAttribute), a =>
{
MaxLengthAttribute maxLength = (MaxLengthAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Max length: {0}", maxLength.Length);
}
},
{ typeof(MinLengthAttribute), a =>
{
MinLengthAttribute minLength = (MinLengthAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Min length: {0}", minLength.Length);
}
},
{ typeof(StringLengthAttribute), a =>
{
StringLengthAttribute strLength = (StringLengthAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "String length: inclusive between {0} and {1}", strLength.MinimumLength, strLength.MaximumLength);
}
},
{ typeof(DataTypeAttribute), a =>
{
DataTypeAttribute dataType = (DataTypeAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Data type: {0}", dataType.CustomDataType ?? dataType.DataType.ToString());
}
},
{ typeof(RegularExpressionAttribute), a =>
{
RegularExpressionAttribute regularExpression = (RegularExpressionAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Matching regular expression pattern: {0}", regularExpression.Pattern);
}
},
{ typeof(ValidateAttribute), a =>
{
ValidateAttribute validateExpression = (ValidateAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Customer Validate: {0}", validateExpression.ToString());
}
},
};
顺带说一下,假如我的实体层是独立的 也需要做一些配置
首先要自定义一个MultiXmlDocumentationProvider
public class MultiXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
/*********
** Properties
*********/
/// The internal documentation providers for specific files.
private readonly XmlDocumentationProvider[] Providers;
/*********
** Public methods
*********/
/// Construct an instance.
/// The physical paths to the XML documents.
public MultiXmlDocumentationProvider(params string[] paths)
{
this.Providers = paths.Select(p => new XmlDocumentationProvider(p)).ToArray();
}
/// Gets the documentation for a subject.
/// The subject to document.
public string GetDocumentation(MemberInfo subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// Gets the documentation for a subject.
/// The subject to document.
public string GetDocumentation(Type subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// Gets the documentation for a subject.
/// The subject to document.
public string GetDocumentation(HttpControllerDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// Gets the documentation for a subject.
/// The subject to document.
public string GetDocumentation(HttpActionDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// Gets the documentation for a subject.
/// The subject to document.
public string GetDocumentation(HttpParameterDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// Gets the documentation for a subject.
/// The subject to document.
public string GetResponseDocumentation(HttpActionDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/*********
** Private methods
*********/
/// Get the first valid result from the collection of XML documentation providers.
/// The method to invoke.
private string GetFirstMatch(Funcstring> expr)
{
return this.Providers
.Select(expr)
.FirstOrDefault(p => !String.IsNullOrWhiteSpace(p));
}
}
public static class HelpPageConfig
{
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
MessageId = "Panasia.UserCenter.WebAPI.Areas.HelpPage.TextSample.#ctor(System.String)",
Justification = "End users may choose to merge this string with existing localized resources.")]
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly",
MessageId = "bsonspec",
Justification = "Part of a URI.")]
public static void Register(HttpConfiguration config)
{
// Uncomment the following to use the documentation from XML documentation file.
//config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/UserCenter.Model.xml"), HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
右键项目属性设置XML文件生成路径
..\XXX.UserCenter.WebAPI\App_Data\XXX.UserCenter.Model.xml
mvc 实体类 自定义验证特性
标签:modify 格式不正确 help public sum ann hone email rate
原文地址:http://www.cnblogs.com/njcxwz/p/7170499.html