繁体   English   中英

如何拥有带有 json 动态成员的 WCF DataContract

[英]How to have a WCF DataContract with a json dynamic member

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

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。 我们还处理请求的序列化,这会导致我们的应用程序出现问题。 我们宁愿避免这种方式。

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

编辑

该服务提供了剩余的 json 资源。 它定义了一个带有 webHttpBinding 的端点。 操作是这样定义的(为了简单起见,被删除了):

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

此外,该服务装饰有以下属性:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

谢谢你。 杰夫

WCF(从 4.5 开始)不支持将任意 JSON 反序列化作为数据契约的一部分。 您需要使用另一个序列化程序来执行此操作 - JSON.NET 是我个人喜欢的序列化程序。 为了能够更改序列化程序,您可以使用不同的消息格式化程序,并在https://github.com/microsoftarchive/msdn-code-gallery-community-sz/tree/master/Supporting%20different%20data的帖子中%20and%20serialization%20formats%20in%20WCF我有一个示例,它就是这样做的 - 用 JSON.NET 替换 WCF 使用的默认序列化。

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

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<string,string> 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 解析器将输出您需要的内容。 我希望我说清楚了。

干杯!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM