Click here to Skip to main content
15,860,972 members
Articles / Web Development / ASP.NET

Automatic ViewState Properties with the ViewState attribute

Rate me:
Please Sign up or sign in to vote.
4.85/5 (19 votes)
28 Jan 2010CPOL2 min read 43K   34   6
Automatic ViewState properties.

Introduction

This article will demo how to implement automatic ViewState properties by attribute.

Background

When we create a ViewState in a page, we usually create a property for this ViewState. Like:

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

Do you think it is kinda boring when you try to create couple of them? Is it possible to make it simple like an Automatic Property? Like:

C#
[ViewStateProperty("UserID")]
protected int ViewState_UserID { get; set;}

or

C#
[ViewStateProperty]
protected int ViewState_UserID { get; set;}

Yes, there is a simple way to make it work by using Attribute.

Code Detail

First step, let's create a BasePage that inherits from System.Web.UI.Page. It is common to create a BasePage for a higher hierarchy. We will make use of Reflection and LINQ here.

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

The second step, create an inner class ViewStateProperty in BasePage that inherits from Attribute. The purpose of this Attribute class is to describe which property in the page is a viewstate property. Theoretically, this attribute targets the viewstate property, so it should be inside BasePage.

C#
[AttributeUsage(AttributeTargets.Property)]
public class ViewStateProperty : Attribute
{
    public string ViewStateName { get; private set; }

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

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

[AttributeUsage(AttributeTargets.Property)] means that this attribute is only available for the property type. The public ViewStateProperty(string in_ViewStateName) constructor is to initilize the ViewState name. By default, the ViewState name is empty. If you want to initialize the ViewState name when setting the attribute, make the default constructor private.

The third step, in the BasePage, create a variable ViewStateProperties to store those properties that have the ViewStateProperty attribute and initialize them in the BasePage default constructor.

C#
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) is used to get all the public and protected properties in the page by Reflection. Where(p => p.GetCustomAttributes(typeof(ViewStateProperty), true).Length > 0) is used to filter those properies that are decorated by the ViewStateProperty attribute.

The forth step is to override the LoadViewState and SaveViewState methods in BasePage:

C#
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(this, null);
    }
    return base.SaveViewState();
}

The goal is to set the viewstate based on the name we set in the ViewStateProperty attribute or the name of the property itself decorated by the ViewStateProperty attribute; and to load the ViewState value to the property decorated by the ViewStateProperty attribute.

Use it

As mentioned in the beginning, it is very easy to implement.

C#
[ViewStateProperty("UserID")]
protected int ViewState_UserID { get; set;}

or

C#
[ViewStateProperty]
protected int ViewState_UserID { get; set;}

In the first one, you set a ViewState called UserID, and in the second, you set a ViewState called ViewState_UserID.

Comment

To implement such properties, you can not set them as private, because GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance) would not return a private property. But protected is enough for our goal.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
BugAll properties end up as dirty Pin
janblomquist123413-Aug-12 9:45
janblomquist123413-Aug-12 9:45 
GeneralA couple of suggestions Pin
varnk4-Feb-10 2:48
varnk4-Feb-10 2:48 
QuestionConfigurable? Pin
ednrg29-Jan-10 3:37
ednrg29-Jan-10 3:37 
AnswerRe: Configurable? Pin
kennysun29-Jan-10 4:32
kennysun29-Jan-10 4:32 
Generalgood one Pin
Pranay Rana28-Jan-10 19:14
professionalPranay Rana28-Jan-10 19:14 
Generalnice Pin
Xmen Real 28-Jan-10 15:58
professional Xmen Real 28-Jan-10 15:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.