Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net asmx web service returning xml instead of json

Why does this simple web service refuse to return JSON to the client?

Here is my client code:

        var params = { };
        $.ajax({
            url: "/Services/SessionServices.asmx/HelloWorld",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            timeout: 10000,
            data: JSON.stringify(params),
            success: function (response) {
                console.log(response);
            }
        });

And the service:

namespace myproject.frontend.Services
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [ScriptService]
    public class SessionServices : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

web.config:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
</configuration>

And the response:

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>

No matter what I do, the response always comes back as XML. How do I get the web service to return Json?

EDIT:

Here is the Fiddler HTTP trace:

REQUEST
-------
POST http://myproject.local/Services/SessionServices.asmx/HelloWorld HTTP/1.1
Host: myproject.local
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://myproject.local/Pages/Test.aspx
Content-Length: 2
Cookie: ASP.NET_SessionId=5tvpx1ph1uiie2o1c5wzx0bz
Pragma: no-cache
Cache-Control: no-cache

{}

RESPONSE
-------
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 19 Jun 2012 16:33:40 GMT
Content-Length: 96

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>

I have lost count of how many articles I have read now trying to fix this. The instructions are either incomplete or do not solve my issue for some reason. Some of the more relevant ones include (all without success):

  • ASP.NET web service erroneously returns XML instead of JSON
  • asmx web service returning xml instead of json in .net 4.0
  • http://williamsportwebdeveloper.com/cgi/wp/?p=494
  • http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/
  • http://forums.asp.net/t/1054378.aspx
  • http://jqueryplugins.info/2012/02/asp-net-web-service-returning-xml-instead-of-json/

Plus several other general articles.

like image 377
njr101 Avatar asked Jun 18 '12 17:06

njr101


3 Answers

Finally figured it out.

The app code is correct as posted. The problem is with the configuration. The correct web.config is:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.webServer>
        <handlers>
            <add name="ScriptHandlerFactory"
                 verb="*" path="*.asmx"
                 type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 resourceType="Unspecified" />
        </handlers>
    </system.webServer>
</configuration>

According to the docs, registering the handler should be unnecessary from .NET 4 upwards as it has been moved to the machine.config. For whatever reason, this isn't working for me. But adding the registration to the web.config for my app resolved the problem.

A lot of the articles on this problem instruct to add the handler to the <system.web> section. This does NOT work and causes a whole load of other problems. I tried adding the handler to both sections and this generates a set of other migration errors which completely misdirected my troubleshooting.

In case it helps anyone else, if I had ther same problem again, here is the checklist I would review:

  1. Did you specify type: "POST" in the ajax request?
  2. Did you specify contentType: "application/json; charset=utf-8" in the ajax request?
  3. Did you specify dataType: "json"in the ajax request?
  4. Does your .asmx web service include the [ScriptService] attribute?
  5. Does your web method include the [ScriptMethod(ResponseFormat = ResponseFormat.Json)] attribute? (My code works even without this attribute, but a lot of articles say that it is required)
  6. Have you added the ScriptHandlerFactory to the web.config file in <system.webServer><handlers>?
  7. Have you removed all handlers from the the web.config file in in <system.web><httpHandlers>?

Hope this helps anyone with the same problem. and thanks to posters for suggestions.

like image 119
njr101 Avatar answered Nov 11 '22 18:11

njr101


No success with above solution, here how I resolved it.

put this line into your webservice and rather return type just write the string in response context

this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(serial.Serialize(city));
like image 29
Ajay Avatar answered Nov 11 '22 17:11

Ajay


If you want to stay remain with Framework 3.5, you need to make change in code as follows.

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
[ScriptService]
public class WebService : System.Web.Services.WebService
{
    public WebService()
    {
    }

    [WebMethod]
    public void HelloWorld() // It's IMP to keep return type void.
    {
        string strResult = "Hello World";
        object objResultD = new { d = strResult }; // To make result similarly like ASP.Net Web Service in JSON form. You can skip if it's not needed in this form.

        System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
        string strResponse = ser.Serialize(objResultD);

        string strCallback = Context.Request.QueryString["callback"]; // Get callback method name. e.g. jQuery17019982320107502116_1378635607531
        strResponse = strCallback + "(" + strResponse + ")"; // e.g. jQuery17019982320107502116_1378635607531(....)

        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        Context.Response.AddHeader("content-length", strResponse.Length.ToString());
        Context.Response.Flush();

        Context.Response.Write(strResponse);
    }
}
like image 13
Kalpesh Desai Avatar answered Nov 11 '22 18:11

Kalpesh Desai