3

我的 HTTP 请求包含一个有效的 JSON 字符串,其中名称“jo\”hn”中间的双引号已转义,如此处所示(由 Fiddler Web 调试器捕获)

{"name":"firstName","value":"jo\"hn"},

注意:请求提交过程使用本文中看到$.ajax(..)的标准 jQuery调用,没有问题。


服务器端问题

我的 C# ASMX Web 服务方法接收以下 C# 字符串值,其中中间双引号未转义(即反斜杠已被删除)。这不能反序列化而不会导致下面看到的错误。

在我将值接收到我的 web 方法之前,这就是过程中发生脱节的地方。就好像 ASP.NET 正在内部处理字符串,方法是取消转义并将其放回原处而不进行转义,更改原始值而不是逐字提供给 web 方法参数。

C#字符串是:

{"name":"firstName","value":"jo"hn"},

ASMX Web 方法大致是:

using System.Web.Script.Serialization;
using System.Web.Script.Services;

[WebMethod]
[ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)]
public string saveData(string values)
{
    JavaScriptSerializer json = new JavaScriptSerializer();
    request = json.Deserialize<List<NameValuePair>>(values.ToString());
                // ^^^ KABOOM! 

可以理解的异常消息是:

{"传入的对象无效,应为 ':' 或 '}'。 (423): [{\"name\":\"plc$lt$zoneHeaderTopNav$searchBoxTopNav$txtWord\",\"value\":\" \"},{\"姓名\":\"称呼\",\"价值\":\"先生\"},{\"姓名\":\"firstName\",\"价值\":\ "joh\"n\"},{\"name\":\"lastName\",\"value\":\"smith\"},{\"name\":\"initial\",\"值\":\"d\"}]"}

在不改变经典 ASMX Web 服务的情况下,我如何才能最好地解决这个问题?

我可能会考虑清理传入请求的前端处理程序,或者可能在 Web 服务方法的开头运行字符串清理。也许是一个不同的 JSON 库。

但是我想知道是否有一个简单的答案:调整配置、使用属性、可能解决问题的设置或重载方法?

我在 Internet 上进行了很多研究,但大多数文章都涉及将 JSON 数据从服务器返回到客户端并处理该领域的问题。


附录说明: Darin Dimitrov要求的完整客户端通话详细信息

更新:达林的答案在这里内联发布,以方便参考

function SaveDraft() {

    $.checklist.checkvalid();
    var formObj = $(':input:not([type=hidden])').serializeArray();

    var request = JSON.stringify(formObj);
    request = request.replace(/'/g, "");

    $.ajax({
        url: "/Service.asmx/saveData",
        type: "POST",

        // *** Original erroneous line: uses string concat - commented out
        // data: "{'values':'" + request + "'}",

        // *** CORRECTED LINE: provides an object instead of a string and calls JSON stringify.
        data: JSON.stringify({ values: request }), 

        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: SaveDraftSuccess,
        error: SaveDraftFail
    });
}

注意:这是生成问题顶部显示的有效 JSON 片段的调用的实施例。

4

1 回答 1

4

为什么要在 Web 服务中进行这种可怕的手动 JSON 反序列化?让我建议你一个更好的方法。

首先定义一个模型:

public class Person
{
    public string Name { get; set; }
    public string Value { get; set; }
}

然后是一个网络方法:

[WebMethod]
[ScriptMethod]
public string SaveData(Person person)
{
    ...
}

然后你可以从javascript调用它。例如使用 jQuery:

$.ajax({
    url: 'foo.asmx/SaveData',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({
        person: {
            name: 'firstName',
            value: ' jo\"h\'n'
        }
    }),
    success: function(result) {
        alert(result.d);
    }
});

没有kabooms了。

此处显示的JSON.stringify方法是内置的现代浏览器,但如果您需要支持旧版浏览器,您可以在页面中包含json2.js脚本。


更新:

现在您已经显示了您的代码,您似乎没有对您的请求进行编码。试试这样:

var formObj = $(':input:not([type=hidden])').serializeArray();
var request = JSON.stringify(formObj);
$.ajax({
    url: "/Service.asmx/saveData",
    type: "POST",
    data: JSON.stringify({ values: request }),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: SaveDraftSuccess,
    error: SaveDraftFail
});

注意事项:您不需要正则表达式来删除单引号,您应该使用它JSON.stringify来正确编码您的请求值。

于 2012-01-25T22:42:03.147 回答