Click here to Skip to main content
15,881,281 members
Articles / Web Development / ASP.NET
Article

Transparent web form persistence in ASP.NET

Rate me:
Please Sign up or sign in to vote.
2.83/5 (12 votes)
10 Jun 20034 min read 57.1K   598   20  
A simple method to create ASP.NET forms that are transparently loaded and saved from/to the database.

Introduction

In order to fully understand this article, you must first read the article: An OO Persistence Approach using Reflection and Attributes in C#.

I am quite new in using .NET. In the past I used J2EE and I was quite happy with it. I must admit that there are a few very nice things in .NET, and ASP.NET is a very big step ahead. The first time I saw some colleagues making an ASP.NET web application, I noticed something that I didn’t quite like. Let me explain. Let’s consider that we need to have a page that can create or update user information, considering that the user has an ID, name, username and password. For each of these, we should have a TextBox and a Label, like:

Sample screenshot

Now, if we want to make a new user, we display this form empty, and when Save is pressed, we get the Text property for each field, and we use it to insert a new record in the database.

If we want to use the same form to update an user, we need to write a method to check if the user ID is in the request query string. If it is, load the values for the user with id = Request.Params[“userId”], and set the values in each TextBox. Then when the Save button is clicked, we must check if it is an insert of an update (we could use a bool IsUpdate field) and perform the needed operation.

This is simple but is much too much to be written especially if you have many forms.

Could we automate this in some way?

Using the Persistence Framework explained in this article, we can make a web form that knows when it is create or update, and it loads and saves itself very easily. For this, I chose to extend the System.Web.UI.UserControl, so that a form like this could be easily integrated in more pages. For this I use the form class:

C#
public class Form : System.Web.UI.UserControl

Now let’s begin. Add a new user control to your web application, called UserForm. Drag from the toolbox, 3 Labels, 3 TextBoxes and a Button. Then double click to go to the code-behind of the user control. We need to make some modifications to it. First, it must extend the Form class instead of System.Web.UI.UserControl.

C#
public abstract class UserForm : Form
{
//controls
    protected System.Web.UI.WebControls.Label Label1;
    protected System.Web.UI.WebControls.Label Label2;
    protected System.Web.UI.WebControls.Label Label3;
    protected System.Web.UI.WebControls.TextBox TextBox1;
    protected System.Web.UI.WebControls.TextBox TextBox2;
    protected System.Web.UI.WebControls.TextBox TextBox3;
    protected System.Web.UI.WebControls.Button Save;

Now we need to overwrite the Page_Load method from the form, in order to make the bindings between controls and User BO properties. This is accomplished using AddSimpleBinding(Control c, string controlProperty, string BOproperty). This tells the form that if it is update, it should load the user object and set (by reflection) the value of each bound control with the value of the BOproperty, and at save time, it sets each BOproperty from the BO, with the value of the controlProperty from the bound control.

C#
protected override void Page_Load(object sender, System.EventArgs e)
{
    // Put user code to initialize the page here
    base.Page_Load(sender,e);
    if(!Page.IsPostBack)
    {
        this.AddSimpleDataBinding(this.TextBox1,"Text","Name");
        this.AddSimpleDataBinding(this.TextBox2,"Text","Username");
        this.AddSimpleDataBinding(this.TextBox3,"Text","Password");
    }
}

Each form must know the BO type that it is used for. This is done using SetDataObjectType(Type BOtype). We just integrate this into OnInit method generated by Visual Studio .NET.

C#
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
    InitializeComponent();
    this.SetDataObjectType(typeof(User));
    base.OnInit(e); 
}
private void InitializeComponent()
{
    this.Save.Click += new System.EventHandler(this.SaveClicked);
    this.Load += new System.EventHandler(this.Page_Load);
}
#endregion

If “Save” is pressed, it should save the data to the database. FormSave() makes the insert or the update needed.

C#
public void SaveClicked(object sender, System.EventArgs e)
{
    this.FormSave();
}

The difference between insert and update is made by checking the request query string to see if it contains a parameter with the same name as, the property of the BO that is mapped as primary key. If you look into the User BO class code, you will find that:

C#
[DBPrimaryKeyField("ID_User",DbType.Int16)]
[DBColumn("ID_User",DbType.Int16,false)]
public long UserID 
{
    //
}

So in this case, it is UserID, so if the query sting is something like : …\....aspx?UserID=50&…, the form gets the data from the database and according to the the bindings declared, the controls are loaded with values. Also an IsUpdate flag is set true and when FormSave is appealed, the form updates the user with UserID = 50, with the new values that the user has modified in the TextBoxes. If the query string did not contain the UserID parameter, the form would have been displayed empty and when FormSave was appealed, a new User BO should be saved to the database.

Now let’s complicate things a little bit. Let’s add to the User BO, two new properties:

C#
[DBTable("Users","dbo")]
[Serializable]
public class User
{
    public User(){}

    private long _id;
    private string _name;
    private string _username;
    private string _password;
    private bool   _active;
    private int _role;
 
//… code for the other properties 
 
    [DBColumn("Active",DbType.String,false)]
    public bool Active
    {
        //set, get
    }
 
 
    [DBColumn("IDRole",DbType.Int16,false)]
    public int IDRole
    {
        //set, get
    }
}

Let’s adapt the form:

Sample screenshot #2

We have added a new CheckBox named CheckBox1 and a new DropDownList, called DropDownList1.

C#
public abstract class UserForm : Form
{
//controls
    protected System.Web.UI.WebControls.Label Label1;
    protected System.Web.UI.WebControls.Label Label2;
    protected System.Web.UI.WebControls.Label Label3;
    protected System.Web.UI.WebControls.TextBox TextBox1;
    protected System.Web.UI.WebControls.TextBox TextBox2;
    protected System.Web.UI.WebControls.TextBox TextBox3;
    protected System.Web.UI.WebControls.Button Save;
//new controls
    protected System.Web.UI.WebControls.CheckBox CheckBox1;
    protected System.Web.UI.WebControls.DropDownList DropDownList1;
//a new dataset
    protected DataSet dataSet1 = new DataSet("mydataset");

We must bind them to User BO properties, so the code becomes:

C#
protected override void Page_Load(object sender, System.EventArgs e)
{
    // Put user code to initialize the page here
    base.Page_Load(sender,e);
    if(!Page.IsPostBack)
    {

First let’s load all roles for the user from the Roles table:

C#
this.ps.LoadDataSet(this.dataSet1,
  "select ID,Name from Roles order by Name","roles")
this.AddSimpleDataBinding(this.TextBox1,"Text","Name");
this.AddSimpleDataBinding(this.TextBox2,"Text","Username");
this.AddSimpleDataBinding(this.TextBox3,"Text","Password");

… and bindings:

C#
this.AddSimpleDataBinding(this.CheckBox1,"Checked","Active");
this.AddListDataBinding(this.DropDownList1,
  "IDRole",this.dataSet1,"roles","Name","{0}","ID");
    }
}

We use the following method to bind the DropDownList:

C#
AddListDataBinding(Control c, string BOproperty, 
    DataSet dataSource, string dataMemberTable, 
    string dataTextField, string formattingExpression, 
    string dataValueField)

Simpler, don’t you think? You do not have to code checking if it is insert or update, data loading for update and especially you do not have to code for the insert or update of the data sent by the user.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


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

Comments and Discussions

 
-- There are no messages in this forum --