【问题标题】:$.ajax response generates error in content-Type:application/json for xml content in json$.ajax 响应在 content-Type:application/json 中为 json 中的 xml 内容生成错误
【发布时间】:2013-11-11 07:07:35
【问题描述】:

这很简单。我想我可能遇到了响应内容类型不兼容的问题

这是我用来发送 jQuery ajax 请求的代码:

 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);

这是我试图在 success 回调中获取的响应。

{
  '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': ''
}

但没有触发成功。我在服务器端请求处理程序中设置context.Response.ContentType = "application/json";,只是将上面的字符串写入响应。正确的方法是什么?

编辑

以这种方式返回:

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

成功了:

 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();

【问题讨论】:

  • 这不是有效的 JSON,您需要使用双引号而不是单引号来分隔字符串。
  • @AnthonyGrist 你的意思是说"svg1":"&lt;svg ..." 会起作用吗?
  • 使用适当的 JSON 编码器而不是自己构建字符串,将是最好的方法。我个人也不喜欢在 JSON 中嵌套 XML 的想法,我会考虑使用纯 XML 格式
  • 您还需要将'name': 'sMan', 更改为"name": "sMan", 等(不要忘记转义svg1 值内的双引号)。但是,是的,如果你真的返回一个有效的 JSON 字符串,我希望它可以工作。
  • @DaveRandom XML 是一个 SVG 图形,他正在传递与该信息相关的信息和图形。我不明白为什么 JSON 不适合这里。我同意如果有效负载只有 xml,那么使用 XML 会更有意义。

标签: javascript jquery ajax json httphandler


【解决方案1】:

您的问题不在于您的 JavaScript 代码或您的 jQuery API 使用。就像others 指出它在服务器端一样。更具体地说,JSON 对象键 have to be double quotes(更一般的 JSON 字符串必须用双引号引起来)。

当您在发布的代码中使用 C# 和 ASP.NET 时。根据您使用的框架,您有其他选择。在所有情况下,我建议您使用对象而不是自己构建 JSON。

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

现在您有了一个代表数据的 C# 对象。

如果您使用的是 ASP.NET MVC 之类的东西:

return Json(yourObj,JsonBehavior.AllowGet);

如果您使用的是 WebAPI,您可以这样做

return yourObj; // will figure out JSON conversion itself

如果您使用的是其他任何东西,或者您使用的任何东西本身都不支持 JSON 响应。您需要从 NuGet 获取 Newtonsoft.JSON 包并返回:

return JsonConvert.SerializeObject(yourObj);

这会将您的对象有效地转换为字符串。

【讨论】:

  • 感谢我使用 C# asp.net 3.4 webforms。感谢 WebAPI 部分,尽管我使用 Newtonsoft 解决了这个问题。任何更多指向 JSON 上的 WebApi 使用示例的指针都会非常好
  • @Nezam WebAPI 执行称为“内容协商”的操作。这意味着您可以从中返回普通的 C# 对象,它会根据客户端的请求确定以什么格式返回它。所以,它通过JSON序列化返回值来自动响应json请求,通过XML序列化返回值来响应xml请求等等。
  • 也就是说asp.net 3.5应该默认支持吧?
  • @Nezam 不,它是 WebAPI 框架的一部分。它在内部使用 Newtonsoft.JSON。
  • 有趣。我不知道 WebAPI 在内部使用 JSON.NET。感谢您的信息!
【解决方案2】:

您应该为返回类型创建一个强类型对象,然后将其转换为 JSON。

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

然后在你的服务器端 .ashx:

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

return JsonConvert.SerializeObject(template);

最后在你的成功回调函数中:

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

【讨论】:

  • 这个答案在几个方面都是错误的。如果我们忽略显而易见的(名称不合适,它是 JsonConvert 而不是 JSONConvert)和错误信息(您不需要需要为它显式声明一个实际的类),给定 OP 的代码 $. parseJSON 仍然不是必需的。更不用说它没有在我 3 分钟前的回答之上添加有用的信息。
  • @BenjaminGruenbaum 这就是你的意见。用于返回数据的强类型类是良好开发的标志。这意味着服务器端方法将始终符合数据契约,而不依赖于魔术字符串。感谢您告知我错字,但您可以编辑它而不是投反对票。谈论过度膨胀的自我!
  • 当您像 OP 对 dataType: "json" 一样发出 jQuery $.ajax 请求时,jQuery 将自动返回 parsed 对象作为结果。见 jQuery 源代码中的_ajaxConvert
  • 看到了吗?比起称某人为骗子,这不是容易的事吗?我更喜欢有人分享知识,而不是居高临下和辱骂。仅仅因为你先回答并不意味着我想复制你。我只是记下了我自己的答案。是的,它有错误。你可以提出“建议”。人们对“建议”反应很好。只是一个“建议”。
猜你喜欢
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-12
  • 2019-03-29
相关资源
最近更新 更多