问题
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.
回答1:
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")>
回答2:
Ok I found a solution. It required two steps:
- Use ExpandoObject to add properties to room_types Object dynamically
- Serialize the return object with Newtonsoft.Json and force the service to return plain text
来源:https://stackoverflow.com/questions/23713965/configuring-wcf-data-contract-for-proper-json-response