views:

296

answers:

2

Let me first put the code snippets here. I am just using the ASP.NET MVC project Visual Studio creates out of the box. So I am just putting the snippets I added to it:

Site.master's head section:

<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
    <script src="../../Scripts/test.js" type="text/javascript"></script>
    <script type="text/javascript">$(document).ready(ready);</script>
</head>  

Content of test.js:

function ready(){
 $.get("/Home/TestAjax", ajaxResponse);
}

function ajaxResponse(data){
    alert("got response from server: " + data);
}

Method in HomeController:

        public String TestAjax()
        {
            if (Request.IsAjaxRequest())
            {
                return "Got ajax request!";
            }
            else
            {
                return "Non-ajax request";
            }
        }

Now the problem I am seeing in Firefox 3.5.30729 (Firebug) is when the ajax request goes out, IIS 7 on the remote box sends Http 302 back, which does the redirect and forces another get request, but it is not asynchronous. Opera also doesn't work so I assume it is the same problem. However, above code works just fine in IE 8, Chrome, and Safari.

On localhost all of the above browsers work as expected including Firefox and Opera -- they all receive "Got ajax request!" as the response from the server.

Anybody have any ideas what's going on here and how to fix it? I am looking for a real solution or at least explanation as to what is going on and why.

A: 

The accepted design of action methods is to return ActionResult. In your case you are returning a string. Try this instead:

public ActionResult TestAjax()
{
    if (Request.IsAjaxRequest())
    {
        return Content("Got ajax request!", "text/plain");
    }
    return View();
}
Darin Dimitrov
I don't see any connection between my question and your suggestion, it is completely irrelevant.ActionResult is a wrapper to take advantage of ASP.NET MVC's capability to generate markup for you. However, in IMO it is just fine to return a string representing JSON block or XHTML, etc that I generated manually.
codelove
No it's not fine. You are not setting the correct content-type which is a wrong design and might be ambiguous for jQuery.
Darin Dimitrov
+1  A: 

So playing with Fiddler did help figure out this issue. Here is what was happening:

The URI in $.get call was causing it to not find the action method, which I indicated in my question that the server was returning a 302. Once Firefox (and Opera) got a 302 from the server, they both tried using "/Home/TestAjax/" (with a slash at the end). However, this time the HTTP header didn't have X-Request-With set to "XMLHttpRequest". So in TestAjax() action method Request.IsAjaxRequest() was false, hence I got "Non-ajax request" back as response.

On the other hand, the reason why IE, Safari, and Chrome were working is because they still had X-Request-With set to "XMLHttpRequest" in redirected request. It is still a mystery to me as to why Firefox and Opera didn't, but I am not going to worry about it at this point.

Quite silly of me to overlook the ending forward slash, but I had no idea it held such importance!

codelove