Andornot Blog

Thursday, September 10, 2009 8:32 AM

Single Search Boxes and the Submit Button

by Jonathan Jacobsen

 

On a search form with only one search term box and one submit button, such as the Quick Search form in the Andornot Starter Kit, the usual user behaviour is to type search terms and press the Enter key. However, there is a longstanding issue with ASP .NET that results in seemingly nothing happening in this case, in some browsers. The form does a weird empty postback because it submits the form, but does not call your ASP.NET submit button's click event: i.e., it does a postback, but does not do anything. The user must instead use the mouse to click the Submit button.

A simple workaround for this is to add a second search box to the form, but make it invisible. For example, add:

<input type="text" style="display:none;" />

Now when the user presses the enter key, the subsequent postback operates as expected (i.e. in the case of the Andornot Starter Kit Quick Search form, it submits the search instead of just doing an "empty" postback that doesn't do anything).

More information on this ASP.NET behaviour is available here. Information on similar behaviour in AJAX Update Panels is in an earlier Andornot developer blog post.

Friday, October 05, 2007 12:40 PM

ASP.NET AJAX Funky Exceptions Part II

by Ted Jardine

Back in the summer I described an issue with ASP.NET AJAX. The session solution dealt with things well enough (and note the update to simply disable session in a page-by-page basis for all but the pages requiring reading or writing to the session), but I'm still getting the occasional SystemWeb.HttpException where there's a problem with the RoleManager module:

Server cannot modify cookies after HTTP headers have been sent.

Stack trace: at System.Web.HttpCookieCollection.Add(HttpCookie cookie) at System.Web.Security.RoleManagerModule.OnLeave(Object source, EventArgs eventArgs)

Of course, because the user doesn't get what's going on (the user just gets the javascript alert box mentioned previously as I haven't intercepted the ASP.NET AJAX thrown error in this application - for this reason, I will be in all future applications), this exception is usually thrown multiple times until the user navigates to another page and then returns to try again. Some users are quite persistent (I recall one being close to 10 times) which would be humorous if it wasn't just so cruel and bad.

It turns out I've had to disable role caching as per the article I mentioned in the last post until either the ASP.NET Role Manager is fixed or I decide to write/find a custom role module. What's interesting is that the roles are not ever being changed in the pages throwing the exception! Harumph. Back to looking at jQuery from here on in.

Has anyone come up with a solution for this so that the roles data store is not being hit on every page load?

UPDATE: As per the comments below, apparently this has been fixed in ASP.NET 3.5, but there are no plans to back port the fix to 2.0.

 

Monday, July 09, 2007 11:23 AM

ASP.NET AJAX and Sys.Webforms.PageRequestManagerServerErrorException

by Ted Jardine

Using ASP.NET AJAX extensively in my latest project I've been sporadically running into the Sys.WebForms.PageRequestManagerParserErrorException. It got to the point that I was contemplating ripping out ASP.NET AJAX completely until this known issue had been ironed out. The various causes for this error are mentioned many different places, but for some samples, go here, here, and here.

Quoting from Eilon Lipton's blog posting, this particular exception is very common and can be caused by any one of the following:

  1. Calls to Response.Write():
    By calling Response.Write() directly you are bypassing the normal rendering mechanism of ASP.NET controls. The bits you write are going straight out to the client without further processing (well, mostly...). This means that UpdatePanel can't encode the data in its special format.
  2. Response filters:
    Similar to Response.Write(), response filters can change the rendering in such a way that the UpdatePanel won't know.
  3. HttpModules:
    Again, the same deal as Response.Write() and response filters.
  4. Server trace is enabled:
    If I were going to implement trace again, I'd do it differently. Trace is effectively written out using Response.Write(), and as such messes up the special format that we use for UpdatePanel.
  5. Calls to Server.Transfer():
    Unfortunately, there's no way to detect that Server.Transfer() was called. This means that UpdatePanel can't do anything intelligent when someone calls Server.Transfer(). The response sent back to the client is the HTML markup from the page to which you transferred. Since its HTML and not the special format, it can't be parsed, and you get the error.

The problem was I wasn't doing any of the above (who uses Response.Write in an ASP.NET application these days?) and I was still sporadically encountering the error - a show stopping error I might add. An error that is popped up in a javascript warning box completely undecipherable to the end user leaving an empty/useless/castrated UpdatePanel in its wake. This of course leaves the end user feeling likewise empty/useless/castrated (to say nothing of the developer).

This post here indicates that there is a problem with the RoleMangerModule or any time you set a cookie to the response in an AJAX callback, which can only be solved by doing one of the following:

  1. Disable caching of cookies in the RoleManager. (yuck)
  2. Handle the Application's Error event to clear the error from the Context selectively (eek).
  3. Disable EventValidation in the web form.
    <%@ Page Language="C#" EnableEventValidation="false" %>
    (gulp)

None of the above are entirely reasonable solutions (especially the last two), and the worst part was that my test page was just a simple contact page that did not change/set roles or cookies, or response.write, or set anything in the session, and wasn't receiving any Unicode character input, or even requiring a user to be logged in, or writing anything to the trace, or anything beyond the basics. And still it blew up. But only occasionally.

In order to faithfully reproduce the error, I finally determined that it must have something to do with sessions as it would only occur if the app pool had recycled and all browser windows had been closed. So, based on one of the comments in one of the above posts, even though I'm not touching session on one of the problem pages, I tried a hack in one of the problem page's Page_Load:

Session["FixAJAXSysBug"] = true;

And lo and behold, we're good to go! So even though I am not using Session on the problem page it must be attempting to set the initial session cookie using the Update Panel callback. So the solution is to make sure the initial session is set before any Update Panel callback takes place. How this got through into production is beyond me.

So if you're sporadically encountering the Sys.Webforms.PageRequestManagerServerErrorException, it could be for any of the above reasons or the fact that your dog/cat/stuffed teddy bear is sitting too close to your monitor. But give the last one a try in every page utilizing AJAX if you're using sessions in your application.

UPDATE: If the problem pages aren't even using session, just turn session off for the page:

<%@ Page EnableSessionState="false" ... %>

Or better yet, set it in your base class to always be off, and turn it on for the pages where you need it on.

UPDATE II: Further developments.

Month List