12

I saw a similar question but it did not resolve my issue. I have a JSON web service in an ASMX file;

The code for the web method

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string GetUserRoles(string JSONUserCode)
        {
            string retRoles = string.Empty;
            List<JSONRole> roles = new List<JSONRole>();

            {... I Populate the roles here ...}

            DataContractJsonSerializer serializer = new
            DataContractJsonSerializer(roles.GetType());
            MemoryStream ms = new MemoryStream();
            serializer.WriteObject(ms, roles);
            string jsonString = Encoding.Default.GetString(ms.ToArray());
            ms.Close();
            return jsonString;
        }

This correctly formats the List correctly but wraps the entire return in XML. Here is the response:

<?xml version="1.0" encoding="utf-8" ?> 
    <string xmlns="http://formshare.com/">
       [{"Name":"Accounts Payable"},{"Name":"Payroll"}]
    </string>

You can view the Response your self by clicking this link:

http://dev.formshare.gologictech.com/JSON/JSONService.asmx/GetUserRoles?JSONUserCode=1234

I need the response to be just:

[{"Name":"Accounts Payable"},{"Name":"Payroll"}]

Any ideas? Thanks for your help.

9 Answers 9

12

The WebMethod is able to serve the same information both as XML and JSON. You need to specify what format you want (dataType) in the client, as you submit your request.

Also, you're not supposed to serialize the object to JSON manually, but rather, return roles, and it will be serialized to JSON if your client requests the data as JSON.

EDIT

jQuery example (note the dataType parameter):

$.ajax({
   type: 'GET',
   url: 'http://dev.formshare.gologictech.com/JSON/JSONService.asmx/GetUserRoles',
   contentType: 'application/json; charset=utf-8',
   dataType: 'json',
   data: '{"JSONUserCode":"1234"}',
   success: myCallback
});

It is worth mentioning that the object will not be returned in exactly the format you specified, but rather, wrapped in an object:

{ d: [ {"Name":"Accounts Payable"}, {"Name":"Payroll"} ] }

This, however, is actually quite desirable, for added security

Sign up to request clarification or add additional context in comments.

5 Comments

Is there anyway to specify the Datatype in a POST?
I'm not sure I follow... the above example is a POST.
I'm sorry, I mean passing the parameter in the URL like the URL I included in my question.
ah, right. I updated my example above to use the url's and parameters that you're using. Using 'GET' instead of 'POST', the data passed in 'data' will be retrieved via querystring rather than form values.
Since $.ajax() won't work for cross-site usage, I have to use $.getJSON(), and my service returns JSONP. I have the same problem, the json result is wrapped in xml. Since I'm using $.getJSON(), I'm not sure how to set the headers to tell the service that I want a json result, not an xml result. Any ideas how to do that, just via the URL? Is there some built-in parameter that .NET services look for in the query string?
3

Turns out it's not dataType that counts but

contentType: 'application/json; charset=utf-8'.  

It worked like a charm.

Comments

1

Make sure your service class has [ScriptService] attribute. This attribute is not added by default.

Comments

1

Try Jayrock for .NET, it's a neat handler for .NET JSON RPC. It'll do exactly what you need. There's a step by step how-to for ASP .NET JSON RPC here.

Comments

1

I made the same mistake by handling the serialization myself. You re not supposed to return string but the object itself.

If you have already developed a hundred Services like this, a work around for you: just created a aspx, ServiceCaller.aspx, remove everything in the html just leave the page directive and use the codebehind to call the service and Response.Write the string. Also take the Service method name as a parameter like "HelloWorld" and use reflection to invoke it.

It's kinda showing your left ear with your right hand but it works. You can also easily integrate a roles management and using reflection get the service name as string check the db if the user can call this service and with reflection Invoke the method.

(any comments on this is welcome :)

Comments

1

Use like this not return string type.Just write

public void Metod()
    {
        json = jss.Serialize(Data);
        Context.Response.Write(json);
    }

Comments

0

We have made another page that calls the service server side and writes the response (in our case an .aspx). We cleaned up all the HTML code, doctype head body, and made the server side code to call the service and response.write it.

(in aspx case just leave the page directive at the top)

this way you can get a clean string.

By the way if this is exposing our application to any security threats or major performance hits, I'd really appreciate the comments. Just too busy to ask it here or search on it :)

Comments

0

Your missed only "static" keyword in method declaration please look into the following it should work.

FYI: All the web methods should be static

[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)]

    public static string GetUserRoles(string JSONUserCode)
    {
        string retRoles = string.Empty;
        List<JSONRole> roles = new List<JSONRole>();

        {... I Populate the roles here ...}

        DataContractJsonSerializer serializer = new
        DataContractJsonSerializer(roles.GetType());
        MemoryStream ms = new MemoryStream();
        serializer.WriteObject(ms, roles);
        string jsonString = Encoding.Default.GetString(ms.ToArray());
        ms.Close();
        return jsonString;
    }

Comments

0

Instead of returning a string in your WebMethod use:

JavaScriptSerializer js = new JavaScriptSerializer();
Context.Response.Write(js.Serialize(YOUR_STRING_TO_OUTPUT));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.