如何构建要发送到 AJAX WebService 的 JSON 对象?

IT技术 c# javascript jquery web-services json
2021-01-11 15:20:05

在尝试在 javascript 中手动格式化我的 JSON 数据并惨遭失败后,我意识到可能有更好的方法。下面是 Web 服务方法和相关类的代码在 C# 中的样子:

[WebMethod]
public Response ValidateAddress(Request request)
{
    return new test_AddressValidation().GenerateResponse(
        test_AddressValidation.ResponseType.Ambiguous);
}

...

public class Request
{
    public Address Address;
}

public class Address
{
    public string Address1;
    public string Address2;
    public string City;
    public string State;
    public string Zip;
    public AddressClassification AddressClassification;
}

public class AddressClassification
{
    public int Code;
    public string Description;
}

Web 服务在使用 SOAP/XML 时效果很好,但我似乎无法使用 javascript 和 jQuery 获得有效响应,因为我从服务器返回的消息与我的手动编码 JSON 有问题。

我无法使用 jQuerygetJSON函数,因为请求需要 HTTP POST,所以我使用的是低级ajax函数:

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
    data: "{\"Address\":{\"Address1\":\"123 Main Street\",\"Address2\":null,\"City\":\"New York\",\"State\":\"NY\",\"Zip\":\"10000\",\"AddressClassification\":null}}",
    dataType: "json",
    success: function(response){
        alert(response);
    }
})

ajax函数正在提交 中指定的所有内容data:,这就是我的问题所在。如何在 javascript 中构建格式正确的 JSON 对象,以便我可以将其插入到我的ajax调用中,如下所示:

data: theRequest

我最终会从表单中的文本输入中提取数据,但现在硬编码的测试数据很好。

如何构建格式正确的 JSON 对象以发送到 Web 服务?


更新:事实证明,正如 TJ 指出的那样,我的请求的问题不是 JSON 的格式,而是我的 JSON 文本不符合 Web 服务的要求。这是基于 WebMethod 中的代码的有效 JSON 请求:

'{"request":{"Address":{"Address1":"123 Main Street","Address2":"suite 20","City":"New York","State":"NY","Zip":"10000","AddressClassification":null}}}'

这带来了另一个问题:在对 ASP.NET Web 服务 (ASMX) 的 JSON 请求中,区分大小写何时重要?

6个回答

答案很简单,根据我之前的帖子如果 ContentType 不是 JSON,我可以从 .asmx Web 服务返回 JSON 吗?JQuery ajax 调用 httpget webmethod (c#) 不起作用

数据应该是 JSON 编码的。您应该对每个输入参数进行单独编码。因为您只有一个参数,所以您应该执行以下操作:

首先将您的数据构建为原生 JavaScript 数据,例如:

var myData = {Address: {Address1:"address data 1",
                        Address2:"address data 2",
                        City: "Bonn",
                        State: "NRW",
                        Zip: "53353",
                        {Code: 123,
                         Description: "bla bla"}}};

然后作为ajax请求的参数给出 {request:$.toJSON(myData)}

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
    data: {request:$.toJSON(myData)},
    dataType: "json",
    success: function(response){
        alert(response);
    }
})

您可以使用来自http://www.json.org/ 的另一个版本 (JSON.stringify) 而不是来自 JSON 插件的 $.toJSON

如果您的 WebMethod 具有类似的参数

public Response ValidateAddress(Request request1, Request myRequest2)

调用data参数的值ajax应该是这样的

data: {request1:$.toJSON(myData1), myRequest2:$.toJSON(myData2)}

或者

data: {request1:JSON.stringify(myData1), myRequest2:JSON.stringify(myData2)}

如果您更喜欢另一个版本的 JSON 编码器。

顺便说一句,不需要在 ajax 中使用 POST。一切都适用于 GET。有关更多信息,请参阅我在答案开头的链接。JSON 劫持存在的问题参见 ( haacked.com/archive/2009/06/25/json-hijacking.aspx ),但有不同的方法可以降低风险,应该继续使用 GET。
2021-03-14 15:20:05
你搞定了。这正好回答了为什么我的代码不起作用以及需要如何格式化 JSON 数据。非常感谢!
2021-03-19 15:20:05
+1 用于正确识别需要包装的数据request才能工作。
2021-03-22 15:20:05
啊,那request一点就是缺少的那一点。很高兴知道。
2021-04-01 15:20:05

您的问题分为两部分:

创建 JSON 字符串

您引用的代码中的 JSON 完全有效。但是手工制作是一种痛苦。正如其他人所说,最简单的方法是创建一个 Javascript 对象,然后创建JSON.stringify它。例子:

var data = {
    "Address": {
        "Address1": "123 Main Street",
        "Address2": null,
        "City": "New York",
        "State": "NY",
        "Zip": "10000",
        "AddressClassification": null
    }
};
data = JSON.stringify(data);

上面的第一步使用 Javascript 对象文字表示法创建一个对象,它是 JSON 的超集(如上所述,它实际上与 JSON 相同,但忽略它)。第二位获取该对象并将其转换为字符串。

当然,上面的值是文字字符串,这是不太可能的。如果您将这些值中的每一个都放在一个变量中,它会是什么样子:

var data = {
    "Address": {
        "Address1": address1,
        "Address2": address2,
        "City": city,
        "State": state,
        "Zip": zip,
        "AddressClassification": null
    }
};
data = JSON.stringify(data);

不管怎样,现在你有了字符串。

将 JSON 字符串发送到 Web 服务

您需要确定 Web 服务是希望 JSON 格式的数据POST 正文,还是希望 JSON 数据是更常见的 name=value URL 编码的 POST 数据中的参数值。我倾向于期待前者,因为 Web 服务似乎专门设计用于处理 JSON 格式的数据。

如果它应该POST 正文,那么,我从来没有用 jQuery 这样做过,而且您引用的内容对我阅读文档来说看起来是正确的。如果它不起作用,我会仔细检查您的对象结构是否真的是他们期望看到的。举例来说,如果它只是验证一个地址,我不知道它是否能接收只是一个Address对象,而不是包含一个Address对象,例如对象:

{
    "Address1": "123 Main Street",
    "Address2": null,
    "City": "New York",
    "State": "NY",
    "Zip": "10000",
    "AddressClassification": null
}

如果它应该是无聊的旧 URL 编码的多部分表单数据中的参数值,那么:

$.ajax({
    type: "POST",
    url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
    data: "paramname=" + encodeURIComponent(data),
    dataType: "json",
    success: function(response){
        alert(response);
    }
})

我已经删除了contentType所以 jQuery 将回退到它的默认值(“application/x-www-form-urlencoded”)并确保我们上面创建的字符串在该内容类型中正确编码。您需要找出paramname要使用的(也许是“地址”并查看我之前关于仅发送地址的评论,而不是包含地址子对象的对象?)。

事实证明,Web 服务需要一个request包含地址对象的对象。这最终成为我的请求失败的原因。有关更多详细信息,请参阅我对问题的更新,并感谢您的详细解释。
2021-03-26 15:20:05
@Ben:啊,好!是的,看到了您的新问题,但对此一无所知(我从未使用过 ASP.Net Web 服务的东西)。Javascript 名称区分大小写,但这并不意味着 .Net 必须以这种方式处理 JSON 数据。
2021-04-10 15:20:05

JSON.stringify将接受一个 javascript 对象并将其转换为字符串。我敢打赌,如果您创建一个 Javascript 对象,例如

var jsonData = {
    address: 'address',
    address1: 'address1',
    address2: 'address2'
};

然后在ajax调用中将jsonData作为'data'传递,然后它将对象转换为json文本。

我会创建一个 javascript 对象,然后调用 JSON.stringify 将其转换为有效的 JSON。你可以从这里下载

你可以这样做:

var address= {};

address["Address1"] = "your val";
address["Address2"] = "your val";
address["City"] = "your val";
address["State"] = "your val";
address["Zip"] = "your val";

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
    data: JSON.stringify(address),
    dataType: "json",
    success: function(response){
        alert(response);
    }
});
是的,你的方式肯定更短,但无论哪种方式都有效。您也可以采用另一种方式,为表单字段指定与对象属性相同的名称,然后执行以下操作: $(':text').each(function() { address[this.id] = this.value; });
2021-03-21 15:20:05
我同意,这有点间接......我假设他从某个表单字段中提取他的数据,所以“你的 val”;实际上是 $("#formElement").val();
2021-04-03 15:20:05
同意创建一个对象,然后对它进行 JSON.stringify'ing,但他为什么要如此间接地创建对象?这会丢失一些东西,因为我不能做换行符,但是:var address = {Address: {Address1: "123 Main Street", .... };是创建该对象的更简洁的方法。(此外,您创建的对象与他使用 JSON 创建的对象的形式略有不同。)
2021-04-07 15:20:05
是的,但即便如此,我还是会写它{Address: {Address1: $("#address1Element").val(), Address2: $("#address2Element").val(), ... }}而不是不断地重新引用 var。但是无论哪种方式。:-)
2021-04-10 15:20:05
的确。:-) 事实上,我用一些表格来做到这一点,可以很方便。
2021-04-11 15:20:05

你需要像这样传递它:

$.ajax({
  type: "POST",
  url: "WebService.asmx/WebMethodName",
  data: "{'fname':'dave', 'lname':'ward'}",
  contentType: "application/json; charset=utf-8",
  dataType: "json"
});

有关更多详细信息,请查看本文:将 jQuery 与 ASP.NET AJAX 一起使用时要避免的 3 个错误

@Giorgi 这正是我的示例代码最初的来源。我想我已经把ajax函数的一般结构写下来了;这是我遇到问题的数据格式。
2021-03-14 15:20:05
@Giorgi:这是无效的 JSON。必须是双引号,而不是单引号。
2021-03-14 15:20:05