views:

108

answers:

3

I have validated the JSON response from my C# Webmethod, so I don't believe that's the problem.

Am trying to parse the result using simple jQuery $.ajax, but for whatever reason I can't get the method to correctly fire and parse the result, also incidentally can't seem to get the function to fire the result. Are their any limits on the size of the JSON object that can be returned.

I also removed this code from inside a "Site.Master" page because it would always refresh when I hit the simple button. Do tags work correctly with jQuery elements like the button input I'm grabbing from the DOM?

function ajax() {
//var myData = { qtype: "ProductName", query: "xbox" };
var myData = { "request": { qtype: "ProductName", query: "xbox"} };
$.ajax({
    type: "POST",
    url: "/webservice/WebService.asmx/updateProductsList",
    data: {InputData:$.toJSON(myData)},
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (msg) {
        // var msg = {__type: "Testportal.outputData", id: "li1234", message: "it's work!", myInt:101}
        alert("message=" + msg.d.ProductName + ", id=" + msg.d.Brand);
    },
    error: function (res, status) {
        if (status === "error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});

}

And the page:

 <asp:Button ID="Button1" runat="server" OnClientClick="ajax();"  Text="Button" /> 

And the Serverside Webmethod:

 public class WebService : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
    public OutputData updateProductsList(InputData request)
    {
        OutputData result = new OutputData();
        var db = new App_Data.eCostDataContext();
        var q = from c in db.eCosts
                select c;

        if (!string.IsNullOrEmpty(request.qtype) && !string.IsNullOrEmpty(request.query))
        {
            q = q.Like(request.qtype, request.query);
        }

        //q = q.Skip((page - 1) * rp).Take(rp);
        result.products = q.ToList();

        searchObject search = new searchObject();

        foreach (App_Data.eCost product in result.products)
        {
            /* create new item list */
            searchResult elements = new searchResult()
            {
                id = product.ProductID,
                elements = GetPropertyList(product)
            };
            search.items.Add(elements);
        }
        return result;

    }

And helper classes:

    public class OutputData
{
    public string id { get; set; }
    public List<App_Data.eCost> products { get; set; }

}
public class InputData
{
    public string qtype { get; set; }
    public string query { get; set; }
}
+1  A: 

What does your server side code method look like? Set a break point. Is it even being hit?

It should look something like:

[WebMethod, ScriptMethod]
public string updateProductsList(string qtype, string query)
{ // stuff
}

Also, your javascript data params do not look formatted correctly.

Kris Krause
Thanks, I just added the method to the post. Also, when doing the jS params. I've had success using this format passing a simple string from the input boxes back and forth, so I decided not to change what works! (at least for that). Ill try this new format.
jordan.baucke
+1  A: 

It seems to me that your problem is that you try to use manual JSON serialization. There are more direct way. You should just declare [ScriptMethod (ResponseFormat = ResponseFormat.Json)] or [ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] and return return direct an object instead of the string from the web method. On the client side (in JavaScript) I strictly recommend you to use JSON.stringify (from json2.js which can be downloaded from http://www.json.org/js.html) for the constructing of the data parameter of jQuery.ajax.

Look at http://stackoverflow.com/questions/2670147/can-i-return-json-from-an-asmx-web-service-if-the-contenttype-is-not-json/2671583#2671583 and http://stackoverflow.com/questions/2737525/how-do-i-build-a-json-object-to-send-to-an-ajax-webservice/2738086#2738086 probably also in http://stackoverflow.com/questions/2651091/jquery-ajax-call-to-httpget-webmethod-c-not-working/2656543#2656543 you have have an interest for more experiments.

Oleg
Thanks Oleg, I'm going to add the "ScriptMethod" (I had this previously, but was failing to properly set this up as I was using the manual serialization as well) and I like the posts you gave me about converting the service to a "WFC Restful" service is a good idea. Ill answer the question with my results if I have good luck.
jordan.baucke
You welcome! I'd like to hear that my other answers are also helpfull for you. Thanks. Good luck for you also and much success in the software development!
Oleg
Thanks, I made some changes based on my reading, but haven't been able to correctly format my object yet to send to the service -- I'm still playing with it, I see I need to give the input type for the webservice in my JSON string for input -- but I keep getting: Error: Object doesn't support this property or method
jordan.baucke
+1  A: 

One problem you may be having is that you aren't doing anything to prevent the button from submitting the form and executing a full postback/reload at the same time you're starting your $.ajax() callback.

I'd suggest wiring this up unobtrusively instead of using the OnClientClick property, like this:

$(document).ready(function() {
  // May need to use $('<%= Button1.ClientID %>') if your Button is 
  //  inside a naming container, such as a master page.
  $('#Button1').click(function(evt) {
    // This stops the form submission.
    evt.preventDefault();

    $.ajax({
      // Your $.ajax() code here.
    });
  });
});

I also agree with Oleg that you should use json2.js for your JSON stringifying and parsing. In newer browsers, that will fall back to the browsers' native implementations of those methods, which is much faster and makes the parsing safer.

Update:

To answer your question about the data, no that doesn't look quite right.

What you want to ultimately send to the server is this (sans formatting):

{"request":{"gtype":"ProductName","query":"xbox"}}

To accomplish that, you want something like this:

var req = { request : { qtype: "ProductName", query: "xbox" }};

$.ajax({
  data: JSON.stringify(req),
  // Remaining $.ajax() parameters
});

Keep in mind that request, qtype, and query must match your server-side structure with case-sensitive accuracy.

You can also be more verbose in defining the request object (which I prefer, personally, to keep things clear and readable):

var req = { };

req.request = { };

req.request.qtype = "ProductName";
req.request.query = "xbox";

I've written a bit more about this here, if you're interested: http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/

Dave Ward
thanks! I also just replaced the JS as a noticed some typos. Does my data look like it's formatted correctly for the web method! And yes, I was wondering about that full post back.
jordan.baucke
thansk Dave- I'm really new to Javascript and haven't used it to do anything as productive as digest a WS before, so this is fun but also a bit tedious! I really appreciate you taking the time
jordan.baucke
No problem. Since you're new to this, I'll also mention Firebug in case you aren't already using it. It allows you to set breakpoints and step through JavaScript, run commands at an interactive console, and view the requests and responses between the browser and server, just to name a few of its features. It's invaluable when you're working on the client-side. http://getfirebug.com
Dave Ward
Thanks Dave, I actually have Firebug, and had given up using it since I wasn't getting much new information, but I do use the watch and breakpoints. I actually got the original idea to leave my UpdatePanels behind from your website: http://encosia.comIt seems to be working now, I just need to parse the JSON response and place it in HTML so I'm still reading.
jordan.baucke
In Firebug, you'll be able to see $.ajax() requests in the console tab. Click the plus-sign icon to expand that open and you'll be able to see what was sent up in the request and what came back down. If the response is JSON, it'll parse that out nicely for you too. That's the part of Firebug that'll help you most right now.
Dave Ward