zoukankan      html  css  js  c++  java
  • 【翻译】创建ViewState特征的自动ViewState属性

    地址:http://www.codeproject.com/KB/viewstate/ViewStateAttribute.aspx

    背景

    当我们在页面中创建一个ViewState,我们通常为ViewState创建一个属性,像这样:

    private int ViewState_UserID
    {
        
    get { return (int) ViewState["UserId"]; }
        
    set { ViewState["UserId"= value; }
    }

    你不觉得创建2个访问器有点令人讨厌吗? 能够使这个简单一些像一个自动的属性吗?像这样:

    [ViewStateProperty("UserID")]
    protected int ViewState_UserID { getset;}

    或者

    [ViewStateProperty]
    protected int ViewState_UserID { getset;}

    代码详情

    第一步:让我们创建一个从System.Web.UI.Page继承的BasePage,为一个更高层次的应用创建BasePage很普遍。我们将在这里使用反射和Linq。

    using System.Reflection;
    using System.Linq;
    public class BasePage : System.Web.UI.Page

    第二步:在BasePage里创建一个继承自Attribute的内部类ViewStateProperty,Attribute类的目的是为了描述页面中的属性是viewstate属性。理论上,attribute的目标是viewstate属性,因此它应该在页面里。

    代码
    [AttributeUsage(AttributeTargets.Property)]
    public class ViewStateProperty : Attribute
    {
        
    public string ViewStateName { getprivate set; }

        
    internal ViewStateProperty(){
            
    this.ViewStateName = string.Empty;
        }

        
    public ViewStateProperty(string in_ViewStateName){
            
    this.ViewStateName = in_ViewStateName;
        }
    }

    [AttributeUsage(AttributeTargets.Property)]意味着该attribute仅用于属性类型。public ViewStateProperty(string in_ViewStateName)构造器的目的是为了初始化ViewState名字。默认地,ViewState的名字为空。当设置attribute的时候,如果你想初始化ViewState名字,请使默认构造器为private

    第三步:在BasePage里,创建一个ViewStateProperties变量,存储那些有ViewStateProperty特征的属性,同时在BasePage里面的默认构造器初始化它们。 

    代码
    private PropertyInfo[] ViewStateProperties;

    protected BasePage() 
    {
        
    this.ViewStateProperties = GetType().GetProperties(
          BindingFlags.NonPublic 
    | BindingFlags.Instance).Where(
          p 
    => p.GetCustomAttributes(typeof(ViewStateProperty), true).Length > 0).ToArray();
    }

    GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance)的作用是在页面里通过反射获得所有publicprotected的属性。Where(p => p.GetCustomAttributes(typeof(ViewStateProperty), true).Length > 0)的作用是过滤那些被ViewStateProperty特征(attribute)修饰的属性.

     

    第四步:在BasePage里面覆盖(override)LoadViewState和SaveViewState方法 

    代码
    protected override void LoadViewState(object savedState)
    {
        
    base.LoadViewState(savedState);
        
    foreach (PropertyInfo property in ViewStateProperties)
        {
            ViewStateProperty[] attributes 
    = (ViewStateProperty[])
              property.GetCustomAttributes(
    typeof(ViewStateProperty), false);
            var LocalName 
    = (string.Empty == attributes[0].ViewStateName) ? 
               property.Name : attributes[
    0].ViewStateName;
            
    if (ViewState[LocalName] != null)
                property.SetValue(
    this, ViewState[LocalName], null);
        }
    }

    protected override object SaveViewState()
    {
        
    foreach (PropertyInfo property in ViewStateProperties)
        {
            ViewStateProperty[] attributes 
    = (ViewStateProperty[])
              property.GetCustomAttributes(
    typeof(ViewStateProperty), false);
            var LocalName 
    = (string.Empty == attributes[0].ViewStateName)? 
              property.Name:attributes[
    0].ViewStateName;
            ViewState[LocalName] 
    = property.GetValue(thisnull);
        }
        
    return base.SaveViewState();
    }

    我们的目标是建立在名称上,我们确定了ViewStateProperty特征或本身

    由ViewStateProperty特征修饰的属性名称;加载ViewState的值到被ViewStateProperty特征修饰的属性上。

     

    使用

     

    在开始谈到的,很容易实现

    [ViewStateProperty("UserID")]
    protected int ViewState_UserID { getset;}

    或者

    ViewStateProperty]
    protected int ViewState_UserID { getset;}

    第一个,设置一个称作UserIDViewState,第二个,设置一个称作ViewState_UserID的ViewState。

     

    注释

    实现这样的属性,你不能设置它们为private,因为GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance)不会返回private属性,但是protected能够做到我们的目标。

    Fighting
  • 相关阅读:
    linux内核中如何访问寄存器?
    uboot加载itb文件后提示"ERROR: new format image overwritten"如何处理?
    如何单独编译Linux内核源码中的驱动为可加载模块?
    openwrt如何打开linux内核的CONFIG_DEVMEM选项?
    openwrt的shell下如何访问寄存器的内容?
    linux系统错误码大全
    第 3 章 文本元素
    第 2 章 基本格式
    第 1 章 HTML5 概述
    第 20 章 项目实战--案例和关于[7]
  • 原文地址:https://www.cnblogs.com/cry/p/1660641.html
Copyright © 2011-2022 走看看