How to get WCF DataContract with json dynamic member

in the project I'm working on, we have a requirement to have a DataContract, which may contain some undefined JSON.

DataMember is some JSON that only makes sense to the client. We want to allow the client to send us json, which we do not know about.

Example:

public class Contract { [DataMember] public int clientId; [DataMember] public string json; } 

Obviously, having a contract defined this way will require the client to exit json as follows:

 { "clientId":1, "json": "{\"test\":\"json\"}" } 

Obviously, this is not what we need. The json user that the client should send us should look like this:

 { "clientId":1, "json": {"test":"json"} } 

Possible solutions that we investigated:

  • use Stream as the contract parameters for the request body. It works, but puts the work on our side, and does not use the framework.
  • Defining "json" as a dynamic object. Does not work. Failed to get property written correctly.
  • Using the Newtonsoft library, modify the standard contract serializer at the WCF endpoint to serialize all inputs to JObject. We also handle serialization on demand, and this causes problems in our application. We would rather avoid this.

Does anyone have a possible solution to this problem?

EDIT

The service offers json leisure resources. It defines a single endpoint with webHttpBinding. The operation is defined as follows (simplified to simplify):

 [WebInvoke(Method = "POST", UriTemplate = "...", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] [OperationContract] Stream Create(Contract c); 

In addition, the service is decorated with the following attribute:

 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 

Thanks. Jf

+6
source share
5 answers

WCF (since 4.5) does not support deserializing arbitrary JSON as part of a data contract. You will need to use another serializer that does this - JSON.NET is the one I personally like. To be able to change the serializer, you can use a different message formatter, and in the message http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters.aspx I have the sample that exactly does this is replacing the default serialization used by WCF with JSON.NET.

Please note that to get arbitrary JSON using this library you will need to change the json property type to the equivalent of arbitrary JSON in JSON.NET, JToken:

 public class Contract { [DataMember] public int clientId; [DataMember] public Newtonsoft.Json.Linq.JToken json; } 
+3
source

Have you customized the class and method using these tags? Before class implementation

 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class xxx {...} 

Before implementing the method

 [OperationContract] [WebGet(ResponseFormat = WebMessageFormat.Json)] public Contract getContract() {...} 
0
source

Have you tried this?

 public class Contract { [DataMember] public int clientId; [DataMember] public Dictionary<string,string> DynamicProperties; } 
0
source

Change the signature to accept the stream. eg:

 public String ProcessJson(Stream jsondata) { //play with jsondata } 

To receive as a stream, override the WebContentTypeMapper methods.

  public class RawWebContentTypeMapper : WebContentTypeMapper { public override WebContentFormat GetMessageFormatForContentType(string contentType) { return WebContentFormat.Raw; } } 
0
source

You do not want the json property to contain a string; you want it to contain an object. Like this:

 public class Contract { [DataMember] public int clientId; [DataMember] public JsonObj json; } public class JsonObj { [DataMember] public string test; } 

This way json parser will give you what you need. I hope I get it.

Hurrah!

-1
source

Source: https://habr.com/ru/post/927851/


All Articles