如何使用json动态成员获得WCF DataContract

在我正在开发的项目中,我们需要一个可以包含一些未定义的JSON的DataContract。

DataMember是一些仅对客户端有意义的JSON。 我们希望允许客户向我们发送我们不知道的json。

例:

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

显然,有一个像这样定义的契约需要客户端像这样转义json:

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

显然,这不是我们所需要的。 客户端应该发送给我们的json应该如下所示:

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

可能的解决方案:

  1. 使用Stream作为请求正文的合约参数。 工作,但将工作放在我们这边,而不是使用框架。
  2. 将“json”定义为DynamicObject。 不起作用。 无法正确写入财产。
  3. 使用Newtonsoft库,更改WCF端点中的默认协定序列化程序,以序列化JObject的所有输入。 我们还处理请求的序列化,它会导致我们的应用程序出现问题。 我们宁愿避免这种方式。

有没有人可以解决这个问题?

编辑

该服务提供restjson资源。 它使用webHttpBinding定义单个端点。 操作定义如下(为简单起见,将其拆除):

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

此外,该服务还使用以下属性进行装饰:

 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 

谢谢。 JF

WCF(自4.5开始)不支持将任意JSON反序列化为数据协定的一部分。 你需要使用另一个串行器 – JSON.NET是我个人喜欢的。 为了能够更改序列化程序,您可以使用不同的消息格式化程序,并在http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters的post中.aspx我有一个完全相同的示例 – 用JSON.NET替换WCF使用的默认序列化。

请注意,要使用该库接收任意JSON,您需要在JSON.NET,JToken中将“json”属性的类型更改为等效于任意JSON:

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

你是否用这些标签配置了类和方法? 课前实施

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

在方法实施之前

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

你试过这个吗?

 public class Contract { [DataMember] public int clientId; [DataMember] public Dictionary DynamicProperties; } 

更改签名以接受流。 例如:

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

要作为流接收,请覆盖WebContentTypeMapper方法。

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

您不希望’json’属性包含字符串,您希望它包含一个对象。 像这样:

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

这样json解析器将输出你需要的东西。 我希望自己清楚明白。

干杯!