Question

I am calling in ASP.NET 4.0 web site a web service (asmx service in same web site) method in 2 different ways. The first method succeeds and always returns a valid JSON object when the asmx web service method is decorated with [ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)].

But the second method fails because the data returned is XML rather than JSON, even though I have decorated the asmx method by [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] (I cannot understand why JSON is not being returned when using GET but it is when using POST?)

  • POST service call

    var serviceurl = "http://localhost:49441/WebService1.asmx/LoginUser" ;
    $.ajax({
        url: serviceurl,
         type: 'POST', 
          contentType: "application/json; charset=utf-8",
         data: JSON.stringify({ userName: userName, password: password }),
         dataType: "json",
        success: function (msg) {
            alert('Web service call succeeded.  ' + msg.d);
        },
        error: function (error) { alert('ERROR has occurred!'); alert(JSON.stringify(error)) }
    });
    
  • GET service call

    var serviceurl = "http://localhost:49441/WebService1.asmx/LoginUser" ;
    $.ajax({
        url: serviceurl,
         type: 'GET', 
          contentType: "application/json; charset=utf-8",
         data: 'userName='+ userName + '&password=' + password,
         dataType: "json",
        success: function (msg) {
            alert('Web service call succeeded.  ' + msg.d);
        },
        error: function (error) { alert('ERROR has occurred!'); alert(JSON.stringify(error)) }
    });
    

  • EDIT 1:

    The Web Service code is as below. When using POST I simply change code to use UseHttpGet = false for the method being called.

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    
    public class WebService1 : System.Web.Services.WebService 
    {
        [WebMethod]
        [PrincipalPermission(SecurityAction.Assert, Unrestricted = true)]
        [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
        public bool LoginUser(string userName, string password)
        {
            bool authenticated = false;
    
            if (userName.ToLower() == "mike" && password.ToLower() == "abcd") 
            {
    
                authenticated = true;
            }
            return authenticated;
        }
    }
    
Was it helpful?

Solution

It appears that its necessary to use POST according to what I read at the following URL in Dave Ward's blog Explanation on why POST is necessary if we are to receive JSON and not Xml when using jQuery, else ASP.Net AJAX enabled web service may respond with XML even when its decorated to return JSON. I have pasted the parts from the above URL that relate to my question.

(So the lesson I have learnt from all this, is to use POST when calling AJAX enabled web services i.e. asmx services, from jQuery.)

Two simple requirements

As I alluded to earlier, the one stipulation is that these ScriptServices only return JSON serialized results if they are requested properly. Otherwise, even a service marked with the attribute will return XML instead of JSON. I can only assume that’s part of the reason for the misconception that ASMX services cannot respond with JSON.

Scott Guthrie has a great post on the specific requirements for coercing JSON out of ScriptServices. To summarize that, requests to the service methods must meet two requirements:

(1) Content-Type – The HTTP request must declare a content-type of application/json. This informs the ScriptService that it will receive its parameters as JSON and that it should respond in kind.

(2) HTTP Method – By default, the HTTP request must be a POST request. It is possible to circumvent this requirement, but it is advisable to stick with HTTP POST requests when dealing with JSON.

That’s it.

As long as those two requirements are satisfied, anything from low-level XMLHttpRequest code, to third-party libraries like jQuery, to ASP.NET AJAX itself can easily retrieve JSON serialized data from ASMX services.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top