views:

17

answers:

0

Symptom: When I make a web service request (from JQuery using .ajax, to ASP.NET .asmx file), if it is made using GET instead of POST, the .asmx file always returns XML instead of JSON. If I flip the call back to posts, it responds just fine as JSON.

Goal: How can I get JSON instead of XML, using HTTP GET?

I've a fair bit of googling already and it isn't the usual suspects like missing ScriptService or not registering handler in web.config. It's behaving like the script handler factory is only working on posts? Please help point me in the right direction here!

Server code:

namespace mynamespace
{
    /// <summary>
    /// Summary description for ServiceAddresses
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class MyService : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
        public string HelloWorld()
        {
            return "Hello World at " + DateTime.Now.ToLongTimeString();
        }
    }
}

Client code:

function testhelloworld(postorget) {
    var webMethod = '/servicedir/MyService.asmx/HelloWorld';
    $.ajax({
        type: ('GET'===postorget)?'GET':'POST',
        url: webMethod,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        data: "{}",
        success: function(msg) {
            $('#info').text(msg.d);
        },
        error: function(xhr, ajaxOptions, thrownError) {
            $('#info').text('Error: ' + xhr.responseText);
        }
    });
}

Works fine if I switch service to UseHttpGet = false and client requests as POST. Sends back XML if I use GET.

Fiddler says request is:

GET http://myserver/servicedir/MyService.asmx/HelloWorld?{} HTTP/1.1
Host: myserver
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 ( .NET CLR 3.5.30729)
Accept: application/json, text/javascript, */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
X-Requested-With: XMLHttpRequest
Referer: http://myserver/test/index.aspx

Response:

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 14 Oct 2010 00:31:44 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 115

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/"&gt;Hello World at 8:31:44 PM</string>

Relevant parts of web.config:

<webServices>
  <protocols>
    <add name="HttpGet"></add>
    <add name="HttpPost"></add>
  </protocols>
</webServices>
. . .
        <remove verb="*" path="*.asmx"/>
        <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
 . . .
  <remove name="ScriptHandlerFactory"/>
  <remove name="ScriptHandlerFactoryAppServices"/>
  <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

Same exact thing but recompiling with UseHttpGet = false and requesting via POST works.

Fiddler says POST request is:

POST http://myserver/servicedir/MyService.asmx/HelloWorld HTTP/1.1
Host: myserver
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 ( .NET CLR 3.5.30729)
Accept: application/json, text/javascript, */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://myserver/test/index.aspx
Content-Length: 2
Pragma: no-cache
Cache-Control: no-cache

{}

Response:

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 14 Oct 2010 00:37:03 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: application/json; charset=utf-8
Content-Length: 33

{"d":"Hello World at 8:37:03 PM"}

Pre-emptively answering the non-answers:

I want to use GET because I would like clients to be able to cache.

I am aware that there are security concerns with get e.g. posted on scott gu's blog.

I know I could not use ASP.NET's script stuff and just do it myself, or try out Jayrock. But, I would like to understand why the stock ASP.NET ScriptHandler isn't working.

related questions