Archive for the ‘Postbacks’ Category

URL Rewriting: Retain URL in Browser Address Bar on Postback

June 16, 2010

The Reason For All Human Existence

We have a HTTPModule which rewrites .html file extensions to .aspx. The aspx file is served but the user sees the URL as .html. This apparently gives us mega Google points which is fundamentally the reason for all human existence and therefore intrinsically justified.

Form Action Attribute: Enemy of Civilisation

The HTTPModule does the URL Rewriting via HTTPContent.Current.RewritePath(realfilename.aspx).
This leaves the the URL that appears in the browser untouched but causes realfilename.aspx to be served to satisfy the Page Request.

BUT RewritePath sets the underlying Form Action Attribute is also set to realfilename.aspx which means that on Postback realfilename.aspx is POSTed to and realfilename.aspx appears in the Browser Address Bar. This drains Google Juice and makes life, work and all existence meaningless. Worse still , the behaviour of the web page was entirely accurate. The page does need to post back to the real page (not the fake one) in order to process the Postback. That happens through the Form Action Attribute: that’s what its for.

False and True Friends

The #1 recommended solution to this problem on teh Greater Google is to remove the Form Action Attribute entirely from the page by implementing a custom HTML Form Control and overriding the Render method. Once this is done, the Form apparently posts back to the URL in the Address Bar. But I didn’t want to mangle my page that way as it leads to downstream problems and besides, I really did need to postback to realfilename.aspx.

Examining one of our existing Web Pages that handled this scenario correctly, I noticed the form was wrapped in an AJAX UpdatePanel. Yeah, that made sense, the full postback would be suppressed maybe changing some behaviours, so I did the same thing – but no bananas – still the postback put realfilename.aspx in the Browser Address Bar.

I then unleashed Firefox’s glorious FIREBUG to have a closer look at the requests generated on the existing good website and the new bad website. The Net Panel showed me that a POST operation was appended to the list of Requests for the page, while on the bad website a brand new GET was invoked, in Firebug’s Net Panel the GET would clear all the entries and repopulate it with entries with the fresh Request. Suck.

An even closer look at the existing website showed me that not only was the whole HTML Form wrapped in an UpdatePanel but that the Web Page was actually a Content Page belonging to a Master Page, not a Web Page in its own right. Would that really make a difference ? YES!

Live Worth Living Again

To suppress the full .NET Postback with an AJAX Postback I had to refactor the Web Page so that it was a Content Page and (of course) link it to a Master Page and wrap the whole of the Content in an UpdatePanel. Like so:

asp:Content ID=”Content1″ ContentPlaceHolderID=”ContentPlaceHolder1″ runat=”server”
!– Whole page content is wrapped in an UpdatePanel.
This means all postbacks will be ajax postbacks which means that html extension will
be retained on postback which is what we need for URL Rewriting.
If we permitted a full postback, the postback would be posted to index.aspx and the address bar would
be updated with the aspx URL thus overwriting the pretty html extension. All this occurs because
the form action attribute is set to index.aspx (the real page) even though the URL has been rewritten
to index.html (the pretty URL)–
asp:UpdatePanel runat=”server” ID=”upIndex”
ContentTemplate
…oodles of Content here…
/ContentTemplate

The corresponding Master Page is but a shell and looks basically like this:
body
form id=”form1″ runat=”server”
asp:ScriptManager runat=”server” /
div
asp:contentplaceholder id=”ContentPlaceHolder1″ runat=”server”
/div
/form
/body

I don’t really know why moving all the content to a Content Page should be required to suppress the full postback. But it works for me.

Advertisements

Enter Key Always Causes Postback

June 29, 2008

Flamin’ annoying.

On this one particular page the enter key would trigger a postback on an Image Button OnClick event, needlessly bringing up our beautiful UserSearch screen over and over and over again.

I hunted though the source code like a Victorian-era botanist on a first-time trip to Patagonia, digging for traces of rogue Javascript, untamed Event Handlers and variegated _DOPOSTBACK calls but found none.

Thoroughly stumped, I reached for Google and ended up at Matt Webster’s blog. His thread (sorry I lost the URL) was stocked with more clues than a warehouse full of Agatha Christie paperbacks and, while not providing the answer exactly, it gave me the gist that the Enter Key has a magnetic attraction for the first ‘Submit’ control it can find – in our case the ultra-assertive Image Button that invoked the UserSearch Control with jihadist fervour.

My solution was a trademark brutal hack.

I just put ANOTHER submit button immediately prior to the Image Button and trapped OnClientClick to return false. So my markup ended up looking like this:


asp:LinkButton ID="hackyDefaultButton" OnClientClick="return false; Visible="false"
asp:ImageButton ID="userSearchButton" OnClick="InvokeUserSearch"

So the Enter Key finds the first submit button on the page which is now the hacky default button and does nothing, unless the Page focus is on the ImageButton in which case it fires InvokeUserSearch.

Brutal hacks. Love ’em.

RFI

Is the above the worst brutal hack you’ve seen ?

Please feel free to rate/flame my hack, but in the interests of constructive criticism, tell me what I should have done better.

Addendum 29-June-2008

This article by 4GuysFromRolla clearly explains the issue and told me that single-line textboxes will almost always cause a submit to be executed on the first button on the HTML form on the Web Page depending on how your browser implements the HTML 2.0 standard.

In the case of IE, a Web Form with more than one single-line Textbox and a submit button will always generate a postback on the first submit button in the form (unless you have done something explicit to modify that behaviour e.g set a DefaultButton on the form).

AND

They solved the issue in exactly the same way I did !!!
Maybe I’m a genius.