如何构建 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