How to have a WCF DataContract with a json dynamic member

丶灬走出姿态 提交于 2019-12-21 09:23:09

问题


at the project I am working on, we have a requirement to have a DataContract that can contain some undefined JSON.

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

Example:

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

Obviously, having a contract defined like that would require the client to escape the json like this:

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

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

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

Possible solutions we investigated:

  1. use Stream as contract parameters for the request's body. Works but puts the work on our side instead of using the framework.
  2. Defining "json" as a DynamicObject. Does not work. Was not able to get the property written properly.
  3. Using Newtonsoft library, change the default contract serializer in the WCF endpoint to serialize all inputs to a JObject. We mst also handle serialization on the request, and it causes problems in our application. We'd prefer to avoid this way.

Does anyone have a possible solution to this problem?

EDIT

The service offers rest json resources. It defines a single endpoint with webHttpBinding. The operation is defined like this (stripped down for simplicity):

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

Also, the service is decorated with following attribute:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

Thank you. JF


回答1:


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

Notice that to receive arbitrary JSON using that library, you'll need to change the type of the "json" property to the equivalent of arbitrary JSON in JSON.NET, JToken:

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



回答2:


Do yo configured the class and the method with these tags? Before class implementation

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

Before method implementation

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



回答3:


Have you tried this?

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



回答4:


Change the signature to accept stream. eg:

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

}

To receive as stream, override WebContentTypeMapper methods.

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



回答5:


You don't want 'json' property to contain a string, you want it to containt an object. Like this:

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

That way the json parser will output what you need. I hope I made myself clear.

Cheers!



来源:https://stackoverflow.com/questions/12916865/how-to-have-a-wcf-datacontract-with-a-json-dynamic-member

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!