asp.net MVC 特性(Attributes)的简单应用--属性特性
属性特性主要应用于类的字段或者属性,以验证是否符合特性。
asp.net MVC里就自带了许多这样的属性特性,例如[Required]、[Display(Name = "用户名")]、[DataType(DataType.Password)]、
[StringLength(100, ErrorMessage = "{0} 必须至少包含 {2} 个字符。", MinimumLength = 6)]等等
它们都是继承了ValidationAttribute这个类,主要用于web前端的自动验证。
不过,今天我要学习的并不是继承ValidationAttribute的属性特性(改天学习了再记上),而是学习服务端的属性特性,用于在服务端验证类的属性特性。
首先创建一个MyStringLenthAttribute类,它继承Attribute(自定义属性的基类)
/// <summary> /// 属性的长度特性 /// </summary> [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)] public sealed class MyStringLenthAttribute:Attribute { public MyStringLenthAttribute(string displayName, int maxLength) { this.DisplayName = displayName; this.MaxLength = maxLength; } //显示的名称,对外是只读的,所以不能通过可选参数来赋值,必须在构造函数中对其初始化。 public string DisplayName { get; private set; } //长度最大值,对外是只读的,所以不能通过可选参数来赋值,必须在构造函数中对其初始化。 public int MaxLength { get; private set; } public string ErrorMessage { get; set; } public int MinLength { get; set; } }
就这么简单,一个可以验证属性长度的attribute就建立起来了,然后要给它赋予实现的方法(核心)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Reflection; using MvcApplication1.Models; using System.Linq.Expressions; using System.Text; namespace MvcApplication1.Filter { public class MyStringLenthValid { /// <summary> /// 属性的长度验证,属性名列表和属性的长度要一一对应 /// </summary> /// <typeparam name="T">实体类</typeparam> /// <param name="classProperties">实体类的属性名列表</param> /// <param name="len">实体类的属性的长度</param> /// <returns></returns> public static bool IsValid<T>(ClassProperty[] classProperties,int[] len) { StringBuilder isValidateFlag=new StringBuilder(); for (int i = 0; i < classProperties.Length; i++) { if (string.IsNullOrWhiteSpace(classProperties[i].PropertyName)) return false; //获取实体类T的公共属性 PropertyInfo p = typeof(T).GetProperty(classProperties[i].PropertyName); //获取此成员的自定义特性的数组 foreach (var attribute in p.GetCustomAttributes(true)) { //如果特性属于MyStringLenthAttribute if (attribute is MyStringLenthAttribute) { //把该特性强制转换成MyStringLenthAttribute MyStringLenthAttribute attr = (MyStringLenthAttribute)attribute; string displayName = attr.DisplayName; int maxLength = attr.MaxLength; int minLength = attr.MinLength; string msg = attr.ErrorMessage; if (len[i] < minLength || len[i] > maxLength) { Console.WriteLine(msg, displayName, minLength, maxLength); isValidateFlag.Append("false"); } else { isValidateFlag.Append("true"); } break; } } } //if(isValidateFlag.ToString().Contains("false")){ // return false; //} //else // return true; return isValidateFlag.ToString().Contains("false") ? false : true; } } }
从上面方法参数ClassProperty[] classProperties,ClassProperty是一个只定义了 实体类属性名的类,主要用于保存需要动态地验证类的属性
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcApplication1.Models { public class ClassProperty { /// <summary> /// 属性名 /// </summary> public string PropertyName { get; set; } public ClassProperty(string propertyName) { this.PropertyName = propertyName; } } }
好的。万事俱备了。最后就来一个测试的实体类Order,其中OrderId和Count都用了MyStringLenthAttribute这个特性
using System; using System.Collections.Generic; using System.Linq; using System.Web; //using System.ComponentModel.DataAnnotations; //using System.ComponentModel.DataAnnotations.Schema; using MvcApplication1.Filter; namespace MvcApplication1.Models { public class Order { public string OrderName { get; set; } [MyStringLenth("订单号", 6, MinLength = 3, ErrorMessage = "{0}的长度介于{1}和{2}之间,请重新输入!")] public string OrderId { get; set; } [MyStringLenth("数量", 3, MinLength = 1, ErrorMessage = "{0}的长度介于{1}和{2}之间,请重新输入!")] public string Count { get; set; } public int Number { get; set; } } }
最后实现验证(上面的代码我都写在了MVC上,下面的是另建的一个控制台,引用MVC的dll)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MvcApplication1.Models; using MvcApplication1.Filter; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string input = string.Empty; string count = string.Empty; Order order; int[] lengths; ClassProperty[] cps = new ClassProperty[] { new ClassProperty("OrderId"), new ClassProperty("Count") }; do { Console.WriteLine("请输入订单号:"); input = Console.ReadLine(); Console.WriteLine("请输入数量:"); count = Console.ReadLine(); order = new Order { OrderId = input, Count = count }; lengths = new int[] { order.OrderId.Length, order.Count.Length };//要和cps一一对应 } while (!MyStringLenthValid.IsValid<Order>(cps, lengths)); Console.WriteLine("订单号输入正确,按任意键退出!"); Console.ReadKey(); } } }
运行结果


浙公网安备 33010602011771号