Click here to Skip to main content
Click here to Skip to main content
Go to top

Automatic ViewState Properties with the ViewState attribute

, 28 Jan 2010
Rate this:
Please Sign up or sign in to vote.
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:

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:

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

or

[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.

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.

[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.

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:

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.

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

or

[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)

Share

About the Author

kennysun
Software Developer
Canada Canada
No Biography provided

Comments and Discussions

 
BugAll properties end up as dirty Pinmemberjanblomquist123413-Aug-12 9:45 
GeneralA couple of suggestions Pinmembervarnk4-Feb-10 2:48 
QuestionConfigurable? Pinmemberednrg29-Jan-10 3:37 
AnswerRe: Configurable? Pinmemberkennysun29-Jan-10 4:32 
Generalgood one PinmemberPranay Rana28-Jan-10 19:14 
Generalnice PinmemberXmen W.K.28-Jan-10 15:58 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140921.1 | Last Updated 28 Jan 2010
Article Copyright 2010 by kennysun
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid