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

Posted

技术标签:

【中文标题】如何构建 JSON 对象以发送到 AJAX WebService?【英文标题】:How do I build a JSON object to send to an AJAX WebService? 【发布时间】:2011-02-13 19:36:25 【问题描述】:

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

[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 存在问题。

我不能使用 jQuery getJSON 函数,因为请求需要 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 服务?


更新:事实证明,我的请求的问题不在于 JSON 的格式,因为 T.J.指出,而是我的 JSON 文本不符合 Web 服务的要求。这是基于 WebMethod 中的代码的有效 JSON 请求:

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

这又引出了另一个问题:When is case sensitivity important in JSON requests to ASP.NET web services (ASMX)?

【问题讨论】:

完全 OT,但是看看你的 data: "\"Address\":\"Address1\" ... ";,记住在 Javascript 中你可以使用单引号来分隔你的字符串,这样会变得更具可读性:data: '"Address":"Address1" ... ',(当然,请确保转义数据中出现的任何' 字符,但至少比" 字符少很多。 @T.J.我很欣赏这个小费。我的 javascript 新手颜色正在显示 :-) :-) 关于 JSON 与 Javascript 对象文字表示法的问题,请向 jhurshman 提出问题,该回答已被删除:JSON 是 Javascript 对象文字表示法的子集,有关详细信息,请参阅 json.org .但它们非常相似(当然)。在您引用的代码中,您输出的字符串是完全有效的 JSON。 (这个网站有时很有用:jsonlint.com) @T.J.感谢您提供指向 jsonlint 的链接。前几天整个下午我都希望有这样的工具。 我认为您不会收到编辑通知,所以:我想到了为什么它可能会拒绝您的(有效)JSON 并更新了我的答案——它可能期待一个对象一个地址,而不是一个包含地址的具有“地址”属性的对象? (详见答案。) 【参考方案1】:

答案很简单,基于我之前的帖子Can I return JSON from an .asmx Web Service if the ContentType is not JSON? 和JQuery ajax call to httpget webmethod (c#) not working。

数据应该是 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)

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

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。 +1 用于正确识别需要将数据包装在 request 中才能正常工作。 你成功了。这正好回答了为什么我的代码不起作用以及 JSON 数据需要如何格式化。非常感谢! 啊,request 位是丢失的位。很高兴知道。【参考方案2】:

您的问题分为两部分:

创建 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 数据成为更多参数的值common name=value URL 编码的 POST 数据。我倾向于期待前者,因为 Web 服务似乎专门设计用于处理 JSON 格式的数据。

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


    "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 对象。这最终成为我的请求失败的原因。有关更多详细信息,请参阅我对问题的更新,并感谢您的详细解释。 @Ben:啊,好!是的,看到了你的新问题,但对此一无所知(我从未使用过 ASP.Net 网络服务的东西)。 Javascript 名称区分大小写,但这并不意味着 .Net 必须以这种方式处理 JSON 数据。【参考方案3】:

JSON.stringify 将获取一个 javascript 对象并将其转换为字符串。我敢打赌,如果你创建一个像

这样的Javascript对象
var jsonData = 
    address: 'address',
    address1: 'address1',
    address2: 'address2'
;

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

【讨论】:

【参考方案4】:

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

你可以这样做:

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

【讨论】:

同意创建一个对象,然后对其进行 JSON.stringify 处理,但他为什么要如此间接地创建对象呢?这会丢失一些东西,因为我不能做换行符,但是:var address = Address: Address1: "123 Main Street", .... ; 是创建该对象的更简洁的方法。 (此外,您创建的对象与他使用 JSON 创建的对象的形式略有不同。) 我同意,这有点间接......我假设他正在从某个表单字段中提取他的数据,所以“你的 val”;实际上是 $("#formElement").val(); 是的,但即便如此,我还是会写 Address: Address1: $("#address1Element").val(), Address2: $("#address2Element").val(), ... 而不是不断地重新引用 var。但是无论哪种方式。 :-) 是的,你的方式肯定更短,但任何一种方式都有效。您还可以采用另一种方式,为表单字段提供与对象属性相同的名称,然后执行以下操作: $(':text').each(function() address[this.id] = this.value; ); 确实如此。 :-) 事实上,我用一些表格来做这件事,可以很方便。【参考方案5】:

你需要像这样传递它:

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

查看这篇文章了解更多详情:3 mistakes to avoid when using jQuery with ASP.NET AJAX

【讨论】:

@Giorgi 这正是我的示例代码最初的来源。我认为,ajax 函数的一般结构已关闭;这是我遇到问题的数据格式。 @Giorgi:这是无效的 JSON。键必须用双引号,而不是单引号。【参考方案6】:

如果这个答案来得太晚了,或者是重复的,所有的道歉。

据我了解,您似乎只是在尝试发送 JSON 对象的字符串。尝试构建一个对象,然后使用它的属性并按原样发送它。

例子:

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

【讨论】:

【参考方案7】:

为自己准备一个可以将任何 javascript 对象转换为 json 的 jquery 插件。例如:

http://plugins.jquery.com/project/json

【讨论】:

以上是关于如何构建 JSON 对象以发送到 AJAX WebService?的主要内容,如果未能解决你的问题,请参考以下文章

使用Ajax(无表单)将POST数据以JSON格式发送到Symfony2 Controller

将 JSON 发送到 web 方法?

如何以json的格式发送到前端

如何通过ajax调用将多个对象发送到Web方法

将 JSON 对象发送到 .NET Web 服务时发生内部服务器错误

ajax传递json数组对象