mvc
来源:互联网 发布:网络共享硬盘无法访问 编辑:程序博客网 时间:2024/06/01 21:14
1.特性
公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为
例如,在一个方法前标注[Obsolete]特性,则调用该方法时VS则会提示该方法已过期的警告
又如,在.Net Remoting的远程对象中,如果要调用或传递某个对象,例如类,或者结构,则该类或结构则必须标注[Serializable]特性。还有,我们在构建XML Web服务时用得很多的一个特性就是[WebMegthod],它可让通过HTTP请求的公开方法的返回值编码成XML进行传递。
特性实际上就是一个类,[Obsolete]特性的实际类名是ObsoleteAttribute,但我们在标注的时候可以不带Attribute后缀,系统在名称转换时会自动给我们加上。
上面说的都是些.NET系统定义的一些特性,当然还有很多。了解如何自定义特性,有利有我们更好的在ASP.NET MVC编程使用特性,比如给Model类的属性标注特性来验证表单输入的合法性
下面我们来模拟一个ASP.NET MVC经常要用到的StringLenth特性,它用于判断用户输入是否超出长度限制。我们现在来模拟它。先定义一个MyStringLenth特性:
// 用户自定义的带有可选命名参数的 MyStringLenthAttribute 特性类。// 该特性通过AttributeUsage限制它只能用在属性和字段上。[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]publicsealedclass MyStringLenthAttribute : Attribute {public MyStringLenthAttribute(string displayName, int maxLength) {this.MaxLength = maxLength;this.DisplayName = displayName; }//显示的名称,对外是只读的,所以不能通过可选参数来赋值,必须在构造函数中对其初始化。publicstring DisplayName { get; privateset; }//长度最大值,对外是只读的,所以不能通过可选参数来赋值,必须在构造函数中对其初始化。publicint MaxLength { get; privateset; }//错误信息,标注时可作为可选命名参数来使用。publicstring ErrorMessage { get; set; }//长度最小值,标注时可作为可选命名参数来使用。publicint MinLength { get; set; }}
上面若不加AttributeUsage限制,特性可以声明在类型(如结构、类、枚举、委托)和成员(如方法,字段,事件,属性,索引)的前面。
然后我们把这个特性应用在下面的Order类之上:
// 应用自定义MyStringLenth特性于Order类的OrderID属性之上。MinLength和ErrorMessage是命名参数。
publicclass Order { [MyStringLenth("订单号", 6,MinLength = 3, ErrorMessage = "{0}的长度必须在{1}和{2}之间,请重新输入!")]publicstring OrderID { get; set; }}
最后我们看看如何使用MyStringLenth特性验证用户输入字符串的长度:
//检查成员字符串长度是否越限。
private static bool IsMemberValid(int inputLength, MemberInfo member) {foreach (object attribute in member.GetCustomAttributes(true)) {if (attribute is MyStringLenthAttribute) { MyStringLenthAttribute attr=(MyStringLenthAttribute)attribute;string displayName = attr.DisplayName;int maxLength = attr.MaxLength;int minLength = attr.MinLength;string msg = attr.ErrorMessage;if (inputLength < minLength || inputLength > maxLength) { Console.WriteLine(msg, displayName, minLength, maxLength);returnfalse; }else {returntrue; } } }returnfalse;}//验证输入是否合法privatestaticbool IsValid(Order order) {if (order == null) returnfalse;foreach (PropertyInfo p intypeof(Order).GetProperties()) {if (IsMemberValid(order.OrderID.Length, p))returntrue; }returnfalse;}publicstaticvoid Main() {string input=string.Empty; Order order;do { Console.WriteLine("请输入订单号:"); input = Console.ReadLine(); order = new Order { OrderID = input }; }while (!IsValid(order)); Console.WriteLine("订单号输入正确,按任意键退出!"); Console.ReadKey();}
2.自动属性
在 C# 3.0 和更高版本中,当属性的访问器中不需要其他逻辑时,自动实现的属性可使属性声明更加简洁。
下面示例演示了属性的标准实现和自动实现:
class Program {class Person {//标准实现的属性int _age;publicint Age {get { return _age; }set {if (value <0 || value >130) { Console.WriteLine("设置的年龄有误!");return; } _age = value; } }//自动实现的属性publicstring Name { get; set; } }staticvoid Main(string[] args) { Person p = new Person(); p.Age = 180; p.Name = "小王"; Console.WriteLine("{0}今年{1}岁。",p.Name,p.Age); Console.ReadKey(); }}
自动属性也可以有不同的访问权限,如:
publicstring Name { get;privateset; }
注意,自动属性不能定义只读或者只写的属性,必须同时提供get和set访问器:
publicstring Name { get; }//编译出错publicstring PetName { set; }//编译出错
3.对象和集合的初始化器
上面我们演示自动属性的时候给对象的实例初始化时是一个一个属性进行赋值的,有多少个属性就需要多少句代码。C# 3.0和更高版本中有了对象集合初始化器,有了它,只需一句代码就可初始化一个对象或一个对象集合的所有属性。这在里先创建一个“商品”类,用于后面的示例演示:
///<summary>/// 商品类///</summary>publicclass Product {///<summary>/// 商品编号///</summary>publicint ProductID { get; set; }///<summary>/// 商品名称///</summary>publicstring Name { get; set; }///<summary>/// 商品描述///</summary>publicstring Description { get; set; }///<summary>/// 商品价格///</summary>publicdecimal Price { get; set; }///<summary>/// 商品分类///</summary>publicstring Category { set; get; }}
基于上面定义好的商品类,下面代码演示了如何通过初始化器来创建商品类的实例对象和集合:
staticvoid Main(string[] args) {//对象初始化器的使用 (可只给部分字段赋值) Product product = new Product { ProductID = 1234, Name = "西瓜", Price = 2.3M };//创建并初始化一个实例 //集合初始化器的使用 List<Product> proList = new List<Product> { new Product { ProductID = 1234, Name = "西瓜", Price = 2.3M },new Product { ProductID = 2345, Name = "苹果", Price = 5.9M },new Product { ProductID = 3456, Name = "樱桃", Price = 4.6M } };
//打印 Console.WriteLine("对象初始化器:{0} {1} {2}", product.ProductID, product.Name, product.Price);foreach (Product p in proList) { Console.WriteLine("集合初始化器:{0} {1} {2}", p.ProductID, p.Name, p.Price); } Console.ReadKey();}
另外还有一些其它类型也可以使用初始化器,如下:
//数组使用初始化器string[] fruitArray = {"apple","orange","plum" };//匿名类型使用初始化器var books = new { Title = "ASP.NET MVC 入门", Author = "小王", Price = 20 };//字典类型使用初始化器
- MVC
- mvc
- MVC
- mvc
- MVC
- MVC
- mvc
- MVC
- MVC
- MVC
- MVC
- MVC
- MVC
- MVC
- MVC
- mvc
- MVC
- MVC
- 【百度之星】Chess
- ios 网络请求和数据库一起封装,block回调
- request获取数据流
- android RXJava2.0(二)--线程控制
- python学习笔记(三)
- mvc
- sql整理之习题..
- Spring MVC静态资源处理
- PHP专题之三大常用缓存
- 耐人寻味的数值类数据交换:不使用第三方变量进行数据交换
- 2017-8-17——2017-8-27
- Lua 5.3 源码分析(三) 全局状态机global_State
- 深入分析ConcurrentHashMap的锁分段技术
- poj 1861 Network