1

This is very simple.I think i may be having an issue with incompatible response content type

This is the code i am using to send a jQuery ajax request:

 var settings = { dataType: 'json',
                url: 'services/loadTemplate.ashx',
                data: JSON.stringify({ 'Name': element.name }), // element.name },
                processData: false,
                //contentType: "application/json; charset=utf-8",
                type: 'POST',
                success: function (data) {
                console.log('successData:'+data);
                    alert(data);
                },
                error: function (xhr, status, error) {
                    var err = eval("(" + xhr.responseText + ")");
                    alert(err.Message);
                }
            }
            $.ajax(settings);

and this is the response i am trying to fetch in success callback.

{
  'name': 'sMan',
  'svg1': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="513" height="490"><desc>Created with Raphaël</desc><defs></defs><text x="50.5" y="50" text-anchor="middle" font="10px &quot;Arial&quot;" stroke="none" fill="#000000" font-size="0px" style="text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 0px; line-height: normal; font-family: Arial;"><tspan>Text</tspan></text><image x="173.5" y="79.5" width="176" height="158" preserveAspectRatio="none" xlink:href="uploaded/75884f70-8872-49c1-8337-2cbbca626b2e.png" id="P28m" fill="#ff0000" stroke="#000000" stroke-width="1" fill-opacity="1" stroke-opacity="1" font-family="Calibri" style="stroke-width: 1px; fill-opacity: 1; stroke-opacity: 1; font-family: Calibri;"></image></svg>',
  'svg2': ''
}

But success is not fired.I am setting context.Response.ContentType = "application/json"; in the server side request handler and am simply writing the above string to response.Whats the correct way to do this?

EDIT:

returning it this way:

 return "{'name':'" + name + @"',
                'svg1':'" + dt.Rows[0]["svg1"].ToString() + @"',
                'svg2':'" + dt.Rows[0]["svg2"].ToString() + "'}";

This worked:

 StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        using (JsonWriter jsonWriter = new JsonTextWriter(sw))
        {
            jsonWriter.Formatting = Formatting.Indented;
            //  jsonWriter.WriteStartArray();
            jsonWriter.WriteStartObject();
            jsonWriter.WritePropertyName("name");
            jsonWriter.WriteValue(name);
            jsonWriter.WritePropertyName("svg1");
            jsonWriter.WriteValue(dt.Rows[0]["svg1"].ToString());
            jsonWriter.WritePropertyName("svg2");
            jsonWriter.WriteValue(dt.Rows[0]["svg2"].ToString());
            jsonWriter.WriteEndObject();

           /* return "{'name':'" + name + @"',
                'svg1':'" + dt.Rows[0]["svg1"].ToString() + @"',
                'svg2':'" + dt.Rows[0]["svg2"].ToString() + "'}";*/
        }

        return sb.ToString();
9
  • 4
    That's not valid JSON, you need to delimit strings using double-quotes, not single-quotes. Commented Oct 31, 2013 at 10:26
  • @AnthonyGrist you mean to say "svg1":"<svg ..." would work? Commented Oct 31, 2013 at 10:31
  • 3
    Use a proper JSON encoder instead of building the string yourself, would be the best way. Also personally I don't like the idea of nesting XML in JSON, I'd look at using a pure-XML format Commented Oct 31, 2013 at 10:32
  • You'd also need to change 'name': 'sMan', to "name": "sMan",, etc (and don't forget to escape the double-quotes inside the value for svg1). But yes, if you actually return a valid JSON string I'd expect it to work. Commented Oct 31, 2013 at 10:32
  • @DaveRandom the XML is an SVG graphic, he is passing information and graphics related to that information. I don't see why JSON is a bad fit here. I agree that if the payload was ONLY xml, then using XML would make more sense. Commented Oct 31, 2013 at 10:44

2 Answers 2

2

Your problem is not in your JavaScript code or in your jQuery API usage. Like others have pointed out it is in the server side. More specifically, JSON object keys have to be double quotes (and more generally JSON strings have to be double quoted).

As you are using C# and ASP.NET from the code you posted. You have alternatives depending on what framework you're using. In All cases, I suggest you use an object instead of building the JSON yourself.

var yourObj = new {name=name,svg1=dt.Rows[0]["svg1"].ToString(),svg2=dt.Rows[0]["svg2"].ToString()}

Now you have a C# object representing your data.

If you're using something like ASP.NET MVC:

return Json(yourObj,JsonBehavior.AllowGet);

If you're using WebAPI you can just do

return yourObj; // will figure out JSON conversion itself

If you're using anything else, or whatever you're using does not support JSON responses itself. You need to get the Newtonsoft.JSON package from NuGet and return:

return JsonConvert.SerializeObject(yourObj);

Which will convert your object to a string validly.

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

5 Comments

thanks i was using C# asp.net 3.4 webforms.Thanks for the WebAPI part although i used Newtonsoft to solve the issue. any more pointers to WebApi usage samples on JSON would be really good
@Nezam WebAPI does something called "Content Negotiation". This means you can return normal C# objects from it and it'll figure out what format to return it in based on what the client requests. So, it automatically responds to json requests by JSON serializing the return value, and to xml requests by XML serializing the return value and so on.
that means asp.net 3.5 should support it by default?
@Nezam no, it's a part of the WebAPI framework. Internally it uses Newtonsoft.JSON.
Interesting. I did not know WebAPI used JSON.NET internally. Thanks for the info!
2

You should create a strong typed object for return type and then convert it to JSON.

public class Template
{
    public string Name {get; set;}
    public string SvgXml1 {get; set;}
    public string SvgXml2 {get; set;}
}

then in your server side .ashx:

var template = new Template 
{
    Name = name,
    SvgXml1 = dt.Rows[0]["svg1"].ToString(),
    SvgXml2 = dt.Rows[0]["svg2"].ToString()
};

return JsonConvert.SerializeObject(template);

and finally in your success callback function:

var name = data.Name;
var svg1 = data.SvgXml1;
...

4 Comments

This answer is wrong in several accords. If we disregard the obvious (the names don't fit, it's JsonConvert not JSONConvert) and the misinformation (you don't need to explicitly declare an actual class for it), given OP's code the $.parseJSON is still not required. Not to mention it does not add useful information on top of my answer from 3 minutes earlier.
@BenjaminGruenbaum That's your opinion. Strongly typed classes for returning data are sign of good development. It means that the server side method will always conform to a datacontract, and not rely on magic strings. Thanks for informing me about the typo, but you could have edited it instead of downvoting. Talk about an over-inflated ego!
When you make a jQuery $.ajax request like OP did with dataType: "json" jQuery will automatically return the parsed object as a result. See _ajaxConvert in the jQuery source code
See? Was that not easy rather than calling someone a cheater? I would prefer someone to share a knowledge rather than be condescending and abusive. Just because you answered first did not mean that I wanted to copy you. I was just jotting down my own answer. And yes it had mistakes. You could have made "suggestions". People react nicely to "suggestions". Just a "suggestion".

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.