Search code examples
jsonvb.netwcfdatacontract

Configuring WCF data contract for proper JSON response


I manage a number of Bed & Breakfast websites and run a kind of booking engine to help the client do bookings directly on their website (as opposed to going to another site to close the deal).

I am working on creating a web service using ASP.NET WCF to create a JSON response about room availability of the hotels I manage. I have configured the web service to serialize the response in JSON. Everything works reasonable well EXCEPT I cannot quite construct the proper objects to get the JSON response I want.

In order do the handoff properly, I am required to return a JSON response structured in the following way:

{
"api_version" : 10 ,
"lang" : "en_US",
"hotels" :
    [
        {
            "name" : "Example Hotel",
            "email" : "concierge@example.com",
            "phone" : "555-555-5555",
            "fax" : "555-555-5555",
            "room_types"  :
                {
                    "Orchid Room" :
                        {
                            "url" : "http://hotel.com/orchid",
                            "desc" : "One queen bed etc."
                        },
                    "Presidential Suite" :
                        {
                            "url" : "http://hotel.com/predidential",
                            "desc" : "One king bed etc."
                        }
                }
        }
    ]
}

I have no problem configuring my WCF service to return objects in JSON serialization. However, where I am confused is how to construct the "room_types" part of the object. Now, the issue is that for each hotel in my system I will have DIFFERENT room types, so I need to somehow dynamically generate the room_types object. But I don't know to structure the objects properly.

Here are the data contracts I have set up so far which do not serialize into JSON properly:

<DataContract()>
Public Class InventoryResponseObject
        <DataMember(order:=0)> Public Property api_version As Integer
        <DataMember(order:=1)> Public Property lang As String
        <DataMember(order:=2)> Public Property hotels As hotelsObject
        <DataMember(order:=3)> Public Property errors As List(Of String)

End Class

<CollectionDataContract()>
Public Class hotelsObject
        Inherits List(Of HotelObject)
        Public Sub New()
        End Sub

End Class

<DataContract()>
Public Class HotelObject
        <DataMember(order:=0)> Public Property name As String
        <DataMember(order:=1)> Public Property email As String
        <DataMember(order:=2)> Public Property phone As String
        <DataMember(order:=3)> Public Property fax As String
        <DataMember(order:=4)> Public Property room_types As RoomTypeCollectionObject

End Class

<DataContract()>
Public Class RoomTypeInfoObject
        <DataMember(order:=0)> Public Property url As String
        <DataMember(order:=1)> Public Property desc As String

End Class

<CollectionDataContract()>
Public Class RoomTypeCollectionObject
        Inherits List(Of RoomTypeInfoObject)
        Public Sub New()
        End Sub

End Class

This will produce the following incorrect JSON resopnse:

{
"api_version" : 10 ,
"lang" : "en_US",
"hotels" :
    [
        {
            "name" : "Example Hotel",
            "email" : "concierge@example.com",
            "phone" : "555-555-5555",
            "fax" : "555-555-5555",
            "room_types"  :[
                        {
                            "url" : "http://hotel.com/orchid",
                            "desc" : "One queen bed etc."
                        },
                        {
                            "url" : "http://hotel.com/predidential",
                            "desc" : "One king bed etc."
                        }
                ]
        }
    ]
}

I am stumped. Any assistance would be hugely appreciated.


Solution

  • Ok I found a solution. It required two steps:

    1. Use ExpandoObject to add properties to room_types Object dynamically
    2. Serialize the return object with Newtonsoft.Json and force the service to return plain text