|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
RequirementsAll code in the example application is intended to be run using .NET 2.0 only. There is no solution for the 1.0/1.1 versions. IntroductionMost of you are familiar with the feature of all web-browsers that when you press the F5 button, the content of a page is refreshed. After the F5 button is pressed, the browser repeats the previous request to the page. Nothing wrong will actually happen when the previous request is made by the GET method. However, problems appear when the last request is made by the POST method. Let's consider an example where a user is transferring money to a shop to pay for some goods. Having completed this operation, the user refreshes the page and as a result the server code is executed once again with the same data. Thus, the user may accidentally pay twice. Where are we going?The purpose of this article is to give you a generic tool to improve your application. Moreover, you will not need to change the application code. If you have a good MVC framework, you can read this article just to find out how people work in worse conditions than you do. This article is intended for those who develop their application without any MVC frameworks or previously developed supporting applications. It will teach you how to make any page refresh manageable. Here we go…Since standard ASP.NET functionality doesn't allow us to track the process of refreshing the page, we should add this functionality ourselves. For this purpose we will use an HTTP module. Also, it's obvious that we should store some marker on a client. Then later we will be able to recognize whether the current request is due to the user having refreshed the page or due to the page being "valid."
We have just defined our core algorithm. This simple condition will regulate all of our further steps. Note that the module does nothing when a page is requested by the GET method. This is our second rule. How to use the Refesh moduleFirst of all, we need to modify Web.config for ASP.NET to see the <system.web>
<httpModules>
<add name="RefreshModule"
type="RefreshModule.Module, RefreshModule"/>
</httpModules>
</system.web>
Than we need to add a reference to the using RefreshModule;
It's enough to get information when a page is being refreshed. Now we can use the [Refresh()]
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack && !RefereshHelper.IsPageRefreshed)
{
// do some work with the submitted date
}
else
{
// do some work when the page is loaded with the GET method
}
}
}
At first it looks great that we can recognize any refresh request while a page is executed. Actually, this approach suits better for new pages due to the fact that we know about this functionality. For existing pages, however, we have to reorganize the code. What if we don't care that the manual refresh handling or the code of our page is complex and we don't want to change anything? In this case, we should modify the attribute slightly to get automatic refresh handling. [Refresh(AutoRedirect = true)]
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
When the [Refresh(MessageModulePath = "MessageControl.ascx")]
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
We pointed to control that will be loaded -- and its output sent to a browser as a response -- while the page is being refreshed. Actually, public interface INotificationProvider
{
string Title
{
get;
}
string HeadHTML
{
get;
}
}
//This is a very simple example
public class NotificationProvider : INotificationProvider
{
public string Title
{
get { return "Custom title"; }
}
public string HeadHTML
{
get
{
return
@"<link rel=""STYLESHEET"" type=""text/css""
href=""styles.css"">
<style>
#info table{
margin: 100px 0px 0px 200px;
}
</style>
";
}
}
}
void Application_Start(object sender, EventArgs e)
{
RefereshHelper.RegisterNotificationProvider(new NotificationProvider());
}
It's going well so far. So let's go ahead and learn how to show a better result to the user. To do that, we have to take these steps:
[Refresh(MessageModulePath = "Notification.ascx")]
[RefreshUI("__RefreshTemplate.aspx", "ContentPlaceHolder1")]
public partial class SmartAttributeNotification : Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
The [Refresh(MessageModulePath = "Notification.ascx")]
//[RefreshUI("__RefreshTemplate.aspx", "ContentPlaceHolder1")]
public partial class SmartIntrefaceNotification : Page,
IRefreshWith<UISample>
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
As you can see, the page inherits a generic SummaryNow you have a tool that will help you to make your application appear and work more professionally. I didn't want to make this module complex with extraneous features and settings, so it should take you just a couple of simple steps to get it working. If you need more features or customization possibilities, it's better to use any well-know application framework. Below you can find two screenshots of a test application. Figure 1: Test page after submit is completed Figure 2: Automatic response result
History
|
||||||||||||||||||||||