Configuring WCF data contract for proper JSON response
Asked Answered
F

2

1

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" : "[email protected]",
            "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" : "[email protected]",
            "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.

Forwent answered 17/5, 2014 at 17:0 Comment(0)
F
0

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
Forwent answered 19/5, 2014 at 6:12 Comment(1)
I eleborated on how I solved my problem here: https://mcmap.net/q/436773/-make-asp-net-wcf-convert-dictionary-to-json-omitting-quot-key-quot-amp-quot-value-quot-tagsForwent
A
0

In your sample of the "proper" json, room_types is not a collection property. In json format, collections are enclosed with [ ], as you have it in your second "wrong" sample. That means that your room_types is in fact an object having two properties "Orchid Room" and "Presidential Suite". Note that the property name with the space is achievable by setting the Name property of the DataMember Attribute: <DataMember(Name:="Orchid Room")>

Anticosti answered 17/5, 2014 at 23:7 Comment(3)
Well, the problem is that i have many different hotels in my database and each hotel has different room types. So, I need to create these properties of room_types "on the fly." Sorry, I don't think I explained myself very wellForwent
I don't know if ou can change the structure of the expected json. If yes, I would first try that and switch to the collection, because it souds like you really need a collection.Anticosti
Yes it seems like it should be a collection, but I confirmed - the expected JSON of room_types is supposed to be one object, rather than a collection. It doesn't feel right. Am trying to get ExpandoObject to "expand" room_types with custom properties...Forwent
F
0

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
Forwent answered 19/5, 2014 at 6:12 Comment(1)
I eleborated on how I solved my problem here: https://mcmap.net/q/436773/-make-asp-net-wcf-convert-dictionary-to-json-omitting-quot-key-quot-amp-quot-value-quot-tagsForwent

© 2022 - 2024 — McMap. All rights reserved.