|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionASP.NET is a fantastic platform for building web applications. One of the main services it provides is the ability to store/cache collected or useful data in memory. ASP.NET supports scoping your cached data in many ways: at the Application level using Conceptually this looks a little like this:
BackgroundAll of these are useful. However there does appear to be one conspicuous oversight. How do you store information between the chain of requests needed for a user to complete a multistage process? There are lots of examples of multistage processes, for example:
You might be thinking that the Session is a good candidate for storing the information captured in each step. However the Session is scoped to a User not to a specific User Process. What is wrong with that? Well, if you have a power user like Dave, who fancies himself as a bit of a PC expert, you’ll find you have users who like to multitask by entering issues simultaneously into multiple windows or tabs. If you used the Session for capturing this information, you could easily lose data as the windows corrupt each other’s data. So what about ViewState? Well, ViewState has some significant limitations. Firstly, by default, your data must be serialized so it can be sent by the server with each response and returned by the browser with each request. Not all objects are serializable, so this puts limitations on what you can put in the ViewState. Also as the ViewState is sent with each request and response, if it gets too big, perceived performance will suffer. Dave and Sally would get annoyed really quickly if their application takes 5 seconds to load each page! Sure these limitations can be overcome if you hook into and modify the default behavior of ASP.NET ViewState; however this is not for the lighthearted. A more unavoidable limitation of ViewState is that it is bound to a single page or control. Multistage processes often involve multiple pages, and unfortunately information can’t easily be transferred from the ViewState of one page to the ViewState of another. So it seems we are lacking an appropriate place to store our information during a multi stage process. I think the solution is to create something called a ‘ProcessContext’. A ProcessContext is a framework you can use to easily create applications that keep users like Dave and Sally happy. The key requirements of a ProcessContext are:
Conceptually, this is how things would look if we had a ProcessContext:
Implementing a ProcessContextThe first step to create a So let's define an interface called The public interface IProcessParticipant
{
string AttachProcessToUrl(string url);
string ProcessID {get;set;}
Hashtable ProcessContext{get;}
}
To actually implement a protected override void OnInit(EventArgs e)
{
ProcessID = Request.QueryString["ProcessID"];
base.OnInit (e);
}
This allows a public string AttachProcessToUrl(string url)
{
if (url.IndexOf("?") == -1)
url = url + "?";
else
url = url + "&";
return url + string.Format("ProcessID={0}",ProcessID);
}
The public string ProcessID
{
get
{
if (ViewState["ProcessID"] == null)
ViewState["ProcessID"] = Guid.NewGuid().ToString();
return ViewState["ProcessID"] as string;
}
set
{
if (value == null) return;
else ViewState["ProcessID"] = value;
}
}
Notice that this implementation uses the ViewState to store the public override bool EnableViewState
{
get
{
return true;
}
set
{
if (value == false) throw new Exception("ViewState is Required");
}
}
Now for clarity we store the information associated with a public Hashtable ProcessContext
{
get
{
Hashtable results = Session[ProcessID] as Hashtable;
if (results == null)
{
results = new Hashtable();
Session[ProcessID] = results;
}
return results;
}
}
We now have a complete working ASP.NET page class that can be used as a base class for all pages that participate in a process and need to share information with other pages in the process. Using the ProcessContextAll you need do to enable the ProcessContext in your web page code is to simply change this line in your code: public class YourPage: System.Web.UI.Page
to this: public class YourPage: ProcessParticipantPage:
Once the ProcessContext["YourKey"] = data;
string stored = ProcessContext["YourKey"] as string;
ProcessContext.Clear();
As you can see this is very simple, hopefully you will find it useful too. To show you just how simple it is, I have created a simple ASP.NET application for Sally to capture her Health and Safety hazards, sorry Dave get your own programmer! The application for Sally has three pages:
On HazardDetails.aspx in the private void btnNext_Click(object sender, System.EventArgs e)
{
string title = this.txtTitle.Text;
string severity = this.txtSeverity.Text;
string description = this.txtDescription.Text;
ProcessContext["title"] = title;
ProcessContext["severity"] = severity;
ProcessContext["description"] = description;
Response.Redirect(this.AttachProcessToUrl("Analysis.aspx"));
}
We do much the same in the private void btnSubmit_Click(object sender, System.EventArgs e)
{
string title = ProcessContext["title"] as string;
string severity = ProcessContext["severity"] as string;
string description = ProcessContext["description"] as string;
string ideas = ProcessContext["ideas"] as string;
string analysis = ProcessContext["analysis"] as string;
string plan = this.txtPlan.Text;
DateTime duedate = DateTime.Parse(this.txtDue.Text);
InsertInDB(title,severity,description,ideas,analysis,plan,due);
}
ConclusionThis application is trivial but it shows the power of the In this article, I have demonstrated a simple way to add a Remember it’s all about Context! UpdateASP.NET 2.0 will provide a feature called Cross Page Posting which allows you to post your web form to the next page in a sequence, this next page then has access to the PreviousPage from which you can access information from the previous form. This can help with Wizards but is still not as powerful as a full fledged Update #2With Thomas Eyde and Hzi's suggestions I have created a standalone version of the It works by looking for a You can still Additionally, if you are concerned about the size of what you are storing in the Now with this version, all you need to do is this: ProcessContext.Current["MyData"] = value; //Store info
string myData = ProcessContext.Current["MyData"] as string; //Access
ProcessContext.Current.Redirect("Page2.aspx");//Redirect the ProcessContext
Perhaps a new article is in order?
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||