I did something similar with a PageToken
class, but I put it in the Master Page so that I could implement it on any page that uses the Master Page. In our code we wrapped the session variables in their own class called Session variables.
We needed a little more functionality for complex pages where postbacks were fine for some actions, but not good for others. Once I identified the action buttons/events/links I then mapped out where the page token should be checked and where it should be generated. I then added code to either generate a new timestamp/key or check existing page tokens. For instance, there could be a list with items to review and the users would click an item and be sent to another page. If they clicked the back button and then tried to click an action button again there was a risk that the data could be modified again. So I would compare the page token and if it didn't match I would requery the data generate a new page token and let the user know that the page was refreshed. If they clicked back two times the hidden field page token still wouldn't match so they'd get the same message.
I made an interface IPageTokenView
because we are using the MVP pattern and this allows our presenter classes access to the page tokens as well.
So for pages that involve transactions we can implement IPageTokenView
. In the code-behind, I wrapped the master page methods. Then I identify transaction events and code it accordingly.
IPageTokenView:
public interface IPageTokenView
{
void GeneratePageToken();
string GetLastPageToken { get;}
bool TokensMatch { get;}
}
Master Page:
#region Tokens
public void GeneratePageToken()
{
SessionVariables currSession = new SessionVariables();
hfMasterPageToken.Value = System.DateTime.Now.ToString();
currSession.PageToken = hfMasterPageToken.Value;
}
public string GetLastPageToken
{
get
{
SessionVariables currSession = new SessionVariables();
return currSession.PageToken;
}
}
public bool TokensMatch
{
get
{
SessionVariables currSession = new SessionVariables();
return (currSession.PageToken != null
&& currSession.PageToken == hfMasterPageToken.Value);
}
}
#endregion Tokens
Sample page:
public void btnGetLatest_Click(object sender, EventArgs e)
{
this.GeneratePageToken();
}
protected void DoUpdate(object sender, DataGridCommandEventArgs e)
{
DataGrid dg = sender as DataGrid;
int pos = dg.EditItemIndex;
string ID;
ID = dg.Items[pos].Cells[1].Text;
this.ResultsMessage = "";
if (pos < 0 || this.TokensMatch == false)
{
btnGetLatest_Click(sender, e);
this.MessageToUser =
"Data reloaded. Click Edit or Insert button to change.";
this.MessageType = MessageToUserType.Success;
this.DisplayMessageToUser = true;
return;
}