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:
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:
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 Label
s, 3 TextBox
es 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
.
public abstract class UserForm : Form
{
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.
protected override void Page_Load(object sender, System.EventArgs e)
{
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.
#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.
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:
[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 TextBox
es. 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:
[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;
[DBColumn("Active",DbType.String,false)]
public bool Active
{
}
[DBColumn("IDRole",DbType.Int16,false)]
public int IDRole
{
}
}
Let’s adapt the form:
We have added a new CheckBox
named CheckBox1
and a new DropDownList
, called DropDownList1
.
public abstract class UserForm : Form
{
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;
protected System.Web.UI.WebControls.CheckBox CheckBox1;
protected System.Web.UI.WebControls.DropDownList DropDownList1;
protected DataSet dataSet1 = new DataSet("mydataset");
We must bind them to User BO properties, so the code becomes:
protected override void Page_Load(object sender, System.EventArgs e)
{
base.Page_Load(sender,e);
if(!Page.IsPostBack)
{
First let’s load all roles for the user from the Roles
table:
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:
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
:
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.