2011-09-08 141 views
0

我试图设置一个WCF Web服务供JavaScript使用JSON和jQuery使用。我注意到,你可以发送JSON没有DataContract如果服务方法参数相匹配的JSON对象的命名结构:将JSON对象作为字典(字符串,对象)传递给WCF Web服务

<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。

就是我希望的是,有一种方法,通过该方法的参数来访问传入的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

好吧我想我想出了如何做到这一点(对于那些感兴趣的人)。我需要绕过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 

这将需要在请求中作为原料流和离开反序列化对我(我更喜欢 - 神奇的少更好)。

除了我需要删除contentType(将其保留为默认值)并将响应的数据类型更改为json(当它是“文本”时,我需要将其反序列化两次由于某种原因):

$.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。