Thursday, March 22, 2012

Why this "refresh detect" work? And how to exploit it?

I'm trying to build a "refresh detect" mechanism, to prevent double inserts when the user presses refresh on the browser at a bad time (and then goes ahead and resubmits...bless their hearts).

The code-behind below is for a test page, very vanilla SQL/TableAdapter/ObjectDataSource/FormView setup, works fine.

I added a hidden field "BRD" ("Browser Refresh Detect") to the page.

The page is so simple and it works so I decided not to reproduce it here (though I'd be happy to if it would help.)

The "refresh detect" in the page code behind actually works, too. It basically stores a GUID.tostring in the hidden field and also in Session("BRD") and compares them. If they're not equal, it assumes a refresh has occurred, and puts out a message to that effect

This question has two parts.

A) Why does this "refresh detect work"? I can't seem to wrap my relatively-newbie-brain around the page cycle to understand what's going on. When it does the compare after a refresh, where has the "old value" hidden field BRD come from? I assume it's a cached version of the rendered page, or something, but I don't understand the mechanics of that.

>> Is there a page event I can use to trap this mechanism so I can see it with my own eyes?

B) Now that I can detect the refresh, how do I interrupt and "turn off" the formview insert? I've set up an "InsertStop" flag at the compare-not-equal, and I've found the formview_inserting event where I can react to that flag (see below) but I don't know how to stop the insert at this point.

Any guidance on this would be appreciated.

Thanks!

=========================================

PartialClass _Default

Inherits System.Web.UI.Page

Dim BRDGAs Guid

Dim InsertStopAsBoolean

ProtectedSub Page_Load(ByVal senderAsObject,ByVal eAs System.EventArgs)HandlesMe.Load

IfNot IsPostBackThen

Me.FormView1.DefaultMode = FormViewMode.Insert

Else

Me.FormView1.DefaultMode = FormViewMode.ReadOnly

EndIf

If IsPostBackThen

IfMe.BRD.Value = Session("BRD")Then

Response.Write("No refresh detected")

Else

Response.Write("USE OF REFRESH DETECTED") '<< works, but WHY?

InsertStop =True

EndIf

EndIf

BRDG = Guid.NewGuid

Session("BRD") = BRDG.ToString

EndSub

ProtectedSub Page_PreRender(ByVal senderAsObject,ByVal eAs System.EventArgs)HandlesMe.PreRender

Me.BRD.Value = Session("BRD")

EndSub

ProtectedSub FormView1_ItemInserting(ByVal senderAsObject,ByVal eAs System.Web.UI.WebControls.FormViewInsertEventArgs)Handles FormView1.ItemInserting

' stop the insert <<< HOW DO I STOP THE INSERT

InsertStop =False

EndSub

EndClass

=========================================

The session cache is being used to store a GUID.

If Session("BRD") = BRDG.ToString

is replaced with

Session.Add("BRD", BRDG.ToString)

it makes it a bit clearer.

Because the GUID value is stored both in the page and in the cache, comparison is possible.

Rgsds,

Martin.


Here is the Simple Solution to get Page Refresh....

Code Behind (VB.NET)

Dim ticks As String = Request("ticks")
Dim sessionTicks As String = CType(Session("ticks"), String)
If IsPostBack Then
If ticks = sessionTicks Then
Session("Refresh") = True
Else
Session("Refresh") = False
Session("ticks") = ticks
End If
End If
lit.Text = "<input type='hidden' name='ticks' value=" & DateTime.Now.Ticks & " />"

On Page HTML

<asp:literal id="lit" runat="server"></asp:literal>
------------------------------

At your insert event u just check the Session("Refresh"), if it is true so its means its Refresh otherwise no.

Hth,
Sajjad

Thanks for inputs. Here's where I think this stands.

B) (how to cancel insert)http://msdn2.microsoft.com/en-us/library/system.componentmodel.canceleventargs.cancel.aspx

ProtectedSub FormView1_ItemInserting(ByVal senderAsObject,ByVal eAs System.Web.UI.WebControls.FormViewInsertEventArgs)Handles FormView1.ItemInserting
' stop the insert
If InsertStop =TrueThen
e.Cancel =True
InsertStop =False
EndIf
EndSub

A) I appreciate the alternate ways to set up the refresh detect. I think the key question for me in this is now:

Where in the page cycle does the page get cached? And how does the "refresh" on the browser work, with respect to this cached page?

Apparently it's cached before the pre-render event, where the hidden field value would be reset...
Knowing this would probably give me a lot of insight into the page cycle, which is still quite blurry for me, despite many readings on it.


Resolution, through a not-particularly-illuminating-newbie-learning-curve-based-on-overcoming-erroneous-assumptions on this at

http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/ASP_DOT_NET/Q_21985213.html

0 comments:

Post a Comment