views:

1286

answers:

5

Issue

I have an aspx page with jQuery code to send an ajax request over to an asmx web service file (on the same website). The response that comes back is not consistent, however, it consistently fires the "error" jQuery callback as opposed to the "success" call back. The status code inconsistently varies between 200, 12030, and 12031. The responseText of the message to the callback inconsistently varies between [blank] and the actual XML that the json webservice returns. I debugged the code, and the webservice does actually execute without any exceptions.

ASPX Code

//Code omitted for brevity

<script type="text/javascript">
jQuery(document).ready(function()
{
  jQuery.ajax({
  type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "CallDequeue.asmx/Dequeue",
    data: "{}",
    dataType: "json",
    success: function(Msg)
    {
      alert('success:' + Msg.responseText);
    },
    error: function(Msg)
    {
      alert('failed:' + Msg.status + ':' + Msg.responseText);
    }
  });
});
</script>

//Code ommitted for brevity

Web Service Code

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class CallDequeue : System.Web.Services.WebService
{
  [WebMethod]
  public string Dequeue()
  {
    return "{\"d\":{\"FirstName\":\"Keivan\"}}";
  }
}
A: 

you say it's json, but it returns xml. i see a slight disconnect there.

just somebody
Right, so when you set the "ScriptService" attribute on a webservice, the response is automatically set to Response.Json on each ScriptMethod by default. The response is returned as JSON wrapped by XML (Not a soap xml message as it would usually return). Does this answer your question?
Kant
the problem here is that if you tell jquery that the response is gonna come in JSON format, but it really is XML (where an element contains CDATA with JSON), you're lying to jquery, and confusing it. when you say JSON, it expects the whole response body to be JSON, period. if the ajax request is really supposed to return XML (as you say), you need to make it with appropriate parameter (s/json/xml/), and then evaluate the JSON data yourself.
just somebody
So how would I make my webservice return JSON without being wrapped in XML? This is in ASP.NET 2.0
Kant
+2  A: 

This question will most likely help you.

Otherwise, I converted this web service to a page method and it worked immediately. Do you have that option?

CS:

public partial class test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    [WebMethod]
    public static string Dequeue()
    {
        return "{\"d\":{\"FirstName\":\"Keivan\"}}";
    }
}

ASPX:

<script type="text/javascript">
    jQuery(document).ready(function()
    {
            jQuery.ajax({
            type: "POST",
              contentType: "application/json; charset=utf-8",
              url: "test.aspx/Dequeue",
              data: "{}",
              dataType: "json",
              success: function(Msg)
              {
                    alert('success:' + Msg.responseText);
              },
              error: function(Msg)
              {
                    alert('failed:' + Msg.status + ':' + Msg.responseText);
              }
            });     
    });

Check this and other Encosia articles out for more information.

Mark Gibaud
+2  A: 

When you mark the service as a ScriptService, it automatically handles the JSON serialization. You shouldn't manually serialize the response.

If you want the return to come back as "FirstName", then you can use a DTO class to control the syntax. Just returning a string, it would come back as {'d':'Keivan'} instead of {'d':{'FirstName':'Keivan'}}.

[ScriptService]
public class CallDequeue : System.Web.Services.WebService
{
  public class PersonDTO
  {
    public string FirstName;
  }

  [WebMethod]
  public PersonDTO Dequeue()
  {
    var p = new PersonDTO();

    p.FirstName = "Keivan";

    return p;
  }
}

A few changes to the calling syntax:

jQuery(document).ready(function() {
  jQuery.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "CallDequeue.asmx/Dequeue",
    data: "{}",
    dataType: "json",
    success: function(Msg) {
      // Unless you're using 2.0, the data comes back wrapped
      //  in a .d object.
      //
      // This would just be Msg.d if you return a string instead
      //  of the DTO.
      alert('success:' + Msg.d.FirstName);
    },
    error: function(Msg) {
      alert('failed:' + Msg.status + ':' + Msg.responseText);
    }
  });
});

You can read more about ASP.NET AJAX's .d wrapper here, if you're interested.

Update:

Using ASP.NET 2.0, you need to install the ASP.NET AJAX Extensions v1.0. Additionally, make sure your web.config is configured for ASP.NET AJAX (most specifically the HttpHandlers section).

Dave Ward
I changed my web service code to just return "Keivan", and it still calls the error: callback because the response is coming back as XML instead of JSON. This is a .net 2.0 web site. How can I make it return pure JSON when returning a string?
Kant
Updated the answer with a couple steps that are necessary to get the JSON serialization working in 2.0.
Dave Ward
A: 

Such a simple answer. My web.config wasn't ajax enabled so all calls (regardless of my webservice being a scriptservice) were returning XML instead of pure json.

Kant
Please update your question instead of adding an answer.
John Saunders
HiI came here to continue this thread again after almost a year. I am also having the same problem as getting error calling web service within $.ajax(). To clarify which web.config file I need to modify for AJX enabled. Is it webservice web.config or the site’s? In my scenario my site is not an asp.net site. It is just a form which validates the users creddentials and it has no web.config file attached to it. So which file I can modify.Thanks in advance
alienavatar
A: 

Try marking up your web method with [ScriptMethod]

As in:

[WebMethod]
[ScriptMethod]
ScottE