我正在尝试使用JSON和jQuery设置一个WCF Web服务供JavaScript使用。我注意到,如果服务方法参数与JSON对象的命名结构匹配,则可以在没有DataContract的情况下发送JSON:
<ServiceContract(Namespace:="http://foo.com/bar")>
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
Public Class WebServices
<OperationContract()>
Public Function Test(fullname As String)
Return CustomFunctions.SerializeJSON(New With {
.SSN = "999-99-9999",
.Birthday = "9/22/1983"})
End Function
End Class
......还有JavaScript ......
$.ajax({
url: "webservices.svc/Test",
data: JSON.stringify({
"fullname" : "John Smith"
}),
type: "POST",
processType: false,
contentType: "application/json; charset=utf-8",
dataType: "text",
success: function (result)
{
console.log(result);
},
error: function (xhr)
{
console.log(xhr.responseText);
}
});
这很好用,但如果我想向Web服务发送大量数据,我可以看到一个问题。当然,参数列表会变得非常冗长和丑陋。另一种方法是创建DataContract。但是,我很可能会创建大量的Web服务,而且每次我想发送超过5个键值对的数据时,我都不想创建全新的DataContract。
我希望有一种方法可以通过方法参数以字典(Of String,Object)的形式访问传入的JSON对象:
<OperationContract()>
Public Function Test(data As Dictionary(Of String, Object))
Dim firstName As String = data("FirstName")
Dim lastName as String = data("LastName")
'...logic goes here...
'....return JSON object
End Function
有人知道这是否可行?大多数人在这种情况下做了什么?我在ASMX工作得很好,所以我知道这是可能的。
答案 0 :(得分:0)
好的,我想我想出了如何做到这一点(对于那些感兴趣的人)。我需要绕过DataContracts(没有任何反对DataContracts,当唯一的客户端是我的AJAX代码时,它们只是一个小问题)。为此,我将Web服务方法更改为:
<OperationContract()>
<WebInvoke(Method:="POST", BodyStyle:=WebMessageBodyStyle.Bare, ResponseFormat:=WebMessageFormat.Json)>
Public Function Test(request As Stream) As String
Using reader As New StreamReader(request)
Dim serializer As New JavaScriptSerializer()
Dim data As Dictionary(Of String, Object) = serializer.Deserialize(Of Dictionary(Of String, Object))(reader.ReadToEnd())
Dim firstName As String = data("FirstName")
Dim lastName As String = data("LastName")
Return serializer.Serialize(New With {.SSN = "999-99-9999",
.Birthday = "9/22/1983"})
End Using
End Function
这会将请求作为原始流接收并将反序列化留给我(我实际上更喜欢 - 魔法越少越好)。
AJAX没有太大变化,除了我需要删除contentType(保留默认值)并将响应的dataType更改为json(当它是“text”时我需要将其反序列化两次某种原因):
$.ajax({
url: "webservices.svc/Test",
data: JSON.stringify({
"FirstName": "John",
"LastName": "Smith"
}),
type: "POST",
dataType: "json",
success: function (result)
{
var data = JSON.parse(result);
console.log(data.SSN);
},
error: function (xhr)
{
console.log(xhr.responseText);
}
});
我希望这有助于任何想要避免DataContracts的人。