{ 100分 } ,求一个特性(Attributes)在Asp.net项目中的实际例子。急,好了立即给分。
如题,请您帮我一把。
[解决办法]
翻了半天,才在箱底找了,此文,希望对你有帮助。
.net Attribute效验的使用方法
近来在做.net的项目,因为会用到实体类,就想在实体类上用Attribute信息来对实体类中的属性进行配制。因为在网上没能找到类似的包,就只能在五一的时候自己写了一个,以下是这个包的使用方法。
首先:需要在web.config中配制验证器。
xml 代码
<configSections>
<sectionGroup name= "Validate ">
<section name= "Validators " type= "Validator.Configuration.ValidateConfigurationSection, Validator "/>
</sectionGroup>
</configSections>
<Validate>
<Validators>
<Validator name= "Email " validateType= "match " validateInfo= "\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* " message= "{0} is\ 't Email "/>
<Validator name= "NotNull " validateType= "inner " validateInfo= "NotNull " message= "{0}不能为空! "/>
<Validator name= "Length " validateType= "inner " validateInfo= "Length " message= "{0}字符串长度不能超过{1}! "/>
<Validator name= "Decimal " validateType= "inner " validateInfo= "Decimal " message= "{0}必须大于{1},{0}必须小于{1} "/>
<Validator name= "TestClass " validateType= "clazz " validateInfo= "Validator.Test.TestObj, Validator " message= "{0}class测试! "/>
</Validators>
</Validate>
Validator 的Name为验证器的名称,这里要以attribute类中工ValidatorName相对应,validateType是一个枚举,他有代表着,验 证器的三个类型,inner是使用内置的验证器,match是正则表达式的验证器,clazz是实现iValidator的类做的验证器。后面validateInfo在种自的类型中有各自的意义,在inner时,他要以Name相同;在match时,他是一个正则表达式;在clazz时,他是一个类的AssemblyInfo信息,要显示的错误信息。
第二部,为每一个验证器写一个Attribut.
c# 代码
public class NotNullValidateType : ValidateType
{
public NotNullValidateType(String sColName)
{
this.ColName = sColName;
this.ValidatorName = "NotNull ";
}
}
在这里我们必须继承ValidateType类,在这个类里我们实现了IValidateType的接口,我们必须为这个接口中的属性进行填值。
其中ValidatorName 是一个必输的,他就是在web.config 的配置的验证器名,ColName 是字段的名字,param 是要传入的参数。
c# 代码
public interface IValidateType
{
string Param{get;set;}
string ValidatorName{get;set;}
string ColName{get;set;}
}
第三部,验证器的编写
inner验证器是内置的验证器,所以我们不能添加他。
match验证器是正则表达式验证器,只要在配置中配制好就可以拥有这个功能。
clazz验证器是自定义类验证器,这个类配置到config中,且已经实现了IValidator.cs类。
c# 代码
public class TestObj :ValidateType, IValidator
{
public TestObj()
{
this.ValidatorName = "TestClass ";
}
public TestObj(String sColName)
{
this.ColName = sColName;
this.ValidatorName = "TestClass ";
}
#region IValidator 成员
public bool validator(object value, ValidatorInfo vi, IValidateType vt)
{
//Console.Write( "hello world gettype ");
return false;
}
#endregion
}
最后, attribute的使用,
c# 代码
public class UserObject
{
string _code;
string _email;
[ValidateType( "NotNull ")]
[TestObj]
[StringLengthValidateType(2)]
public string Code
{
get { return _code; }
set { _code = value; }
}
[EmailValidateType(null)]
public string Email
{
get { return _email; }
set { _email = value; }
}
decimal _age;
[DecimalValidateType(0,50)]
public decimal Age
{
get { return _age; }
set { _age = value; }
}
}
以上就是attribut的使用方法,我们只要ValidateUtile.validate(uo)方法就可以对这个对象进行效验了。
最后, attribute的使用,
c# 代码
public class UserObject
{
string _code;
string _email;
[ValidateType( "NotNull ")]
[TestObj]
[StringLengthValidateType(2)]
public string Code
{
get { return _code; }
set { _code = value; }
}
[EmailValidateType(null)]
public string Email
{
get { return _email; }
set { _email = value; }
}
decimal _age;
[DecimalValidateType(0,50)]
public decimal Age
{
get { return _age; }
set { _age = value; }
}
}
以上就是attribut的使用方法,我们只要ValidateUtile.validate(uo)方法就可以对这个对象进行效验了。
[解决办法]
看不出你有做为框架师的迹象。说出你为什么这样想,我或许会给你一些让你惊愕的应用。使用Attribute的设计师经常是大型产品的“灵魂”级的人物。
[解决办法]
事实上,诸如 Attribute(特性)、Reflection(反射)之类看似比较“高级”的技术,常规应用程序开发中应用的比较少,更多的是用于,类库、自动化工具、IDE、组件开发等等,他们都与Meta data(元数据)紧密相关,而且都是主要在运行时交互。
.net 中 Reflection 就是充分利用了类型元数据(编译器自动生成),而 Attribute 就是特定语言(这里是C#)提供给开发者实现自定义元数据的接口
BTW,应用程序开发中,使用 Reflection 需要特别考虑性能问题,不要以为好用,就到处用之。
让我举例,一时,我真无法举个经典,易懂,融合实际的,又是 ASP.NET 项目的 Attribute 应用出来。
真有兴趣研究,不如参考 .net 类库中以下命名空间,包含了大量的 Attribute 类,因为他们都是与组件设计、控件设计、开发环境相关的类,比我们自己提供应该更权威,更具方法学的考虑
System.ComponentModel 命名空间
http://msdn2.microsoft.com/zh-cn/library/System.ComponentModel(VS.80).aspx
如 System.ComponentModel.DescriptionAttribute 就是让 VS 属性面板获取控件的说明信息
这些的具体用法,你可以找个 IL 反汇编工具,反汇编 .net 类库,推荐工具 Reflector (just google it)
反汇编成源码,你会看到 System.Web.UI.WebControls.Button/LinkButton/GridView/.... 这些类的类、方法、属性、事件....上面添加了大量的 Attribute,他们几乎全是与设计器(如 VS IDE)相关的
至于,如何设计器如何获取我们给这些 Attribute 的添加的信息,那就是反射的功劳了
Hope helpful.
[解决办法]
可以说整个System.Reflection名称空间下的对象模型完全就是由系统及用户自定义元数据映射而成
即使是系统内置实现的属性,如果用户代码以一种和.NET框架完全不一样的方式去理解该属性也是完全有可能的.
看看下面的代码,并在属性类的构造函数处设置断点,以调试模式启动该程序,命中断点后,查看调用堆栈(含非用户代码),你可以更好的理解属性的应用场合.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
[assembly:WindowsApplication1.testAttr(1)]
[assembly:WindowsApplication1.testAttr(2)]
namespace WindowsApplication1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Name = "Form1 ";
this.Text = "Form1 ";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
private void Form1_Load(object sender, System.EventArgs e)
{
this.GetType().Assembly.GetCustomAttributes(true);
}
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class,AllowMultiple=true)]
public class testAttr:System.Attribute
{
[STAThread]
static void Main()
{
(new Form1()).Show();
}
public testAttr(int t)
{
MessageBox.Show( "Test Attribute " + t);
}
}
}
[解决办法]
从进程的观点来看,属性类在使用者的进程空间被实例化.其代码的运行上下文是调用者进程.
而其数据(如果有的话)来自于被编译模块的元数据中.
比如说系统内置的DllImport属性,它被编译器使用,它在编译器的运行上下文中执行代码.
类似的象ToolboxItem这样的属性被集成开发环境(IDE)实例化.