8

I have a WCF endpoint that is like such:

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, UriTemplate = "")]
Stream DoWork(Dictionary<string, string> items);

In order to pass anything to my service, I have to structure my JSON like such:

{"items":[{"Key":"random1","Value":"value1"}, {"Key":"random2","Value":"value2"}]}

What I actually want it to look like is this:

{"items":{"random1":"value1","random2":"value2"}}

Is there any way to accomplish this?

Brandon
  • 10,744
  • 18
  • 64
  • 97
  • @NewBeeee - It's not easy. You want to set [DataContractJsonSerializerSettings.UseSimpleDictionaryFormat](https://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.usesimpledictionaryformat.aspx) but it's never exposed, so you'll need to replace the entire serializer. See https://stackoverflow.com/questions/6792785 or https://stackoverflow.com/questions/11003016. Possibly https://stackoverflow.com/questions/33554997 will be required also. – dbc Jul 13 '16 at 20:00
  • @NewBeeee - In fact I think https://stackoverflow.com/questions/6792785/replace-wcf-default-json-serialization is a duplicate. – dbc Jul 13 '16 at 20:03

4 Answers4

4

Is it an option for you to change the DoWork parameter to a string, then use a Json deserializer in the method to convert it to the appropriate format?

competent_tech
  • 44,465
  • 11
  • 90
  • 113
0

I have been searching for the same solution. I managed to get it working by using 'JavaScriptSerializer'. You have to set the function output to 'Stream' not 'String'.

Public Function hotel_availability(ByVal data1 As Stream) As Stream Implements IMyTestAPI.hotel_availability
....
Dim serializer As New JavaScriptSerializer()
Dim serializedResult = serializer.Serialize(a_response)
Dim json = Encoding.UTF8.GetBytes(serializedResult)
Dim a_result as  New MemoryStream(json)
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8"

return a_result
Douglas
  • 53,759
  • 13
  • 140
  • 188
yohan
  • 1
0

You basically need a SerializableDynamic Object, so that your method will look like this:

[OperationContract]
[WebInvoke(...)]
Stream DoWork(SerializableDynamicObject items);

You can see a good guide on how to build the SerializableDynamic Object from a Dictionary here: (see Solution section). Hope this helps...

Community
  • 1
  • 1
-1

You may have better success using the Newtonsoft JSON serializer.

It is available here http://www.newtonsoft.com/json for free and is also available as a NuGet package.

I have found to be much more flexible than the stock JSON serializers.

Also, it looks like your URITemplate is empty. I haven't used the wrapped body style, but with bare body style you need the URITemplate to be populated.

John Meyer
  • 2,296
  • 1
  • 31
  • 39