8

在我正在进行的项目中,我们需要有一个可以包含一些未定义 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。我们还需要处理请求的序列化,这会导致我们的应用程序出现问题。我们宁愿避免这种方式。

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

编辑

该服务提供休息 json 资源。它使用 webHttpBinding 定义了一个端点。操作是这样定义的(为简单起见,简化了):

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

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

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

谢谢你。杰夫

4

5 回答 5

3

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我有一个完全可以做到这一点的示例 - 将 WCF 使用的默认序列化替换为 JSON.NET。

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

public class Contract 
{ 
    [DataMember] 
    public int clientId; 
    [DataMember] 
    public Newtonsoft.Json.Linq.JToken json; 
} 
于 2012-10-16T22:29:41.627 回答
0

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

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

方法实现前

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public Contract getContract() {...}
于 2012-10-16T14:30:04.763 回答
0

你试过这个吗?

public class Contract 
{ 
    [DataMember] 
    public int clientId; 
    [DataMember] 
    public Dictionary<string,string> DynamicProperties; 
}
于 2012-10-16T18:09:45.487 回答
0

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

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

}

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

 public class RawWebContentTypeMapper : WebContentTypeMapper 
    {
        public override WebContentFormat GetMessageFormatForContentType(string contentType)
        {            
                return WebContentFormat.Raw;       
        }   
    }
于 2014-06-11T10:24:29.797 回答
-1

您不希望“json”属性包含字符串,而是希望它包含对象。像这样:

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

这样 json 解析器将输出您需要的内容。我希望我说清楚了。

干杯!

于 2012-10-16T15:51:45.693 回答