===== Update: Clarified need for global.asax file and contents =====
A fantasy sports (fantasy basketball / fantasy football) website I do some work for had some Ajax related issues some time ago. I recently came across the problem somewhere else and figured it might make sense to write it up.
There were error messages that were not consistent. In testing a page there might not be any problems, but then when it goes to a production server the problem shows up. Or maybe it does not have a problem when being accessed from one location, but then another user does have a problem. If you have these sorts of symptoms I’m here to tell you it might not be Ajax’s problem. Instead, we may need to blame the firewall. Typically the ajax error will say something like :
“Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled. Details: Error parsing near ‘ … [some more here] …
Some firewalls do not recognize AJAX headers. This causes the firewall to alter the message (by removing the header) that our servers send to the browser viewing the page. When that happens, the user’s browser cannot make sense of the response and gives the error mentioned above. We actually had users who were able to convince their network admin to disable an option on their firewall (temporarily) that is typically called something like “REMOVE UNKNOWN HEADERS”. When the option was disabled, the site functioned normally for them.
Unfortunately, disabling the users firewall is not a viable solution. One recommendation might be to have the admin “tell” the firewall about the header so it will recognize it and quit removing it. Depending on the type of firewall (a product called Watchguard was the offender in our test case) there may be a way to make certain headers (the ajax header) known rather than disabling them all. There is nothing to “fix” for us as it is more a flaw with the firewall than anything else; if you are encountering this problem you will need to work with your network admin on the problem.
All of that being said, we found that it can also often be fixed by code on the website end! That is a much better option, yes? So here’s all you have to do.
<asp:contentplaceholder id=”ContentPlaceHolderCodeForAjaxStrippingFirewalls” runat=”server”>
<script language=’javascript’ type=”text/javascript”>
function beginRequest(sender, args)
{
var r=args.get_request();
if (r.get_headers()[“X-MicrosoftAjax”])
{
b=r.get_body();
var a=“__MicrosoftAjax=” + encodeURIComponent(r.get_headers()[“X-MicrosoftAjax”]);
if (b!=null && b.length>0)
{
b+= “&” ;
}
else b= “” ;
r.set_body(b+a);
}
}
</script>
</asp:contentplaceholder>
Note: I put this inside a contentplaceholder (I am using masterpages) so I didn’t have to include it manually on every page. If you are not utilizing masterpages then you could just put the script on each page that uses ajax.
Now, we need something to call this. I put a call to it in my global.asax file within the method Application_BeginRequest:
void Application_BeginRequest(object sender, EventArgs e)
{
// first event in the pipeline.
// I’m going to use this to try to intercept ajax headers when they get all messed up by firewalls
// I got the information about how to do this the below url:
// http://forums.asp.net/p/1144748/1850717.aspx
HttpRequest request = HttpContext.Current.Request;
if (request.Headers[“X-MicrosoftAjax”] == null && request.Form[“__MicrosoftAjax”] != null)
{
ArrayList list = new ArrayList();
list.Add(request.Form[“__MicrosoftAjax”]);
Type t = request.Headers.GetType();
//lock (request.Headers)
//{
t.InvokeMember(“MakeReadWrite”, System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, request.Headers, null);
t.InvokeMember(“InvalidateCachedArrays”, System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, request.Headers, null);
t.InvokeMember(“BaseSet”, System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, request.Headers, new object[] { “X-MicrosoftAjax”, list });
t.InvokeMember(“MakeReadOnly”, System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, request.Headers, null);
//}
}
}
Do those two things and and the problem goes bye bye, and the network admins get to keep their silly little rules in place.
Note2: I found the hint about what might be causing the problem here. I’m not entirely sure where I found the fix… it was a long day thank you… but it works.
Hey Man,
I am having this issue also. I don’t have master pages at all. I have cut and pasted your code in my web page. Can you tell me how I need to call this? I am fairly new to web development. Thanks a lot.
Dan
Hmmm… Well, I have seen to have fixed this. My problem is related to a dropdownlist and it sits on a update panel. Seems the update panel is problem. I added this in the mark up for the update panel. RenderMode=”Inline” … it seemed to have worked. I have tested several time.
THanks anyways… now just need to understand what Inline means.
I was wrong, that didn’t fix it. It doesn’t happen all the time.
If you could answer my first question, that would be great. Thanks.
Dan, you should be able to simply paste the code. You do not have to call it. If you are not within a master page you can remove the “contentplaceholder” tags from the example I provided.
Remember, the fact that this CAN happen due to a firewall does not mean it is always due to the firewall. Make sure you don’t have any code issuing Response.Write() type commands. These will always break ajax and are the more likely culprit. If none of the “usual suspects” are the cause then this post may well apply. If there are no firewalls between the client and the webserver (including built in ones on the client) you can eliminate this post as a possible solution.
This was happening to me, but the reason was the updatepanel was inside an asp:panel on the page. moving the updatepanel and ajax control outside the panel solved the problem, although it made it more difficult to achieve the same functionality on the page.
Thanks, Kelly. I haven’t heard of that causing a problem before although now that you mention it I seem to recall having issues the first time I tried to use ajax with a panel. I’m curious now and will see if I can test it out with a simple ajax app and cause the same issue.
Just wanna say your post is impressive . The lucidity in your article is just respectable and I can affirm that you are an specialist on this area . Well with your authorization approve me to grab your rss feed to be updated with future articles . Thank you very much indeed and please keep up the sound activity.