开发者

Passing a JSON object as a Dictionary(Of String, Object) to WCF Web Service

I'm trying to setup a WCF web service to be consumed by JavaScript using JSON and jQuery. I've noticed that you can send JSON without a DataContract if the service method parameters match the naming structure of the JSON object:

<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

...And 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);
    }
});

This works great, but I can see an issue coming up if I want to send the web service a lot of data. Naturally the parameter list is going to get really long and ugly. The alternative is to create a DataContract. However I'm most likely going to be creating a lot of web services and I don't want to have to create a brand new DataContract every time I want to send data longer than 5 key-value pairs.

What I'm hoping is that there's a way to access the incoming JSON object as a Dictionary(Of String, Object) through the method parameter:

<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

Does anyone know if this is possible? What do most people do in this sc开发者_如何学JAVAenario? I had this working great in ASMX so I know it's possible.


Ok I think I figured out how to do this (for those interested). I need to bypass the DataContracts (nothing against DataContracts, they're just a litte much when the only client is my AJAX code). In order to do this I changed the web service method to look like this:

<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

This will take in the request as a raw stream and leave the deserialization up to me (which I actually prefer - the less magic the better).

The AJAX didn't change much except for the fact that I needed to remove the contentType (leave it as default) and change the dataType of the response to json (when it was "text" I needed to deserialize it twice for some reason):

$.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);
    }
});

I hope this helps anyone wanting to avoid DataContracts.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜