使用稍微复杂的方法引用WCF服务时获取“递归收集数据协定”

时间:2012-08-22 08:32:02

标签: .net wcf exception-handling wsdl

如果我在WCF服务中仅使用简单方法,一切正常。但是,如果我包含以下方法,则会出现问题:

[OperationContract]
public List<KeyValuePair<string, string>> GetAllAccounts()
{
    return AccountBusiness.GetAllAccounts();
}

从其他项目引用服务时出现此错误:

  

警告5自定义工具警告:无法导入wsdl:portType       详细信息:运行WSDL导入扩展时抛出异常:   System.ServiceModel.Description.DataContractSerializerMessageContractImporter       错误:键入'Newtonsoft.Json.Linq.JToken'是不受支持的递归收集数据合同。考虑修改   要删除的集合'Newtonsoft.Json.Linq.JToken'的定义   引用自己。       XPath到错误源:// wsdl:definitions [@targetNamespace ='http://tempuri.org'] / wsdl:portType [@ name ='NodeService'] C:\ inetpub \ wwwroot \ MyclientProject \ Service   引用\ NodeService \ Reference.svcmap 1 1 MyClientNode

如果我删除上面的方法,重新编译并更新引用,那么它工作正常。但是当我添加上述方法时,我始终会收到此警告。

我发现的一个建议是卸载Visual Studio 2012并修复Visual Studio 2010.我不想这样做。

另一个suggested取消选中“在所有引用的程序集中重用类型”,但这会弄乱方法签名并且无法使用。

3 个答案:

答案 0 :(得分:6)

事实证明,错误是由于我从NuGet安装了一个包含Json.NET的Microsoft Web API包。卸载后,它可以正常工作。

这可能是您的答案 - 如果没有,请查看您已安装的其他软件包(您不需要)并将其删除。

答案 1 :(得分:1)

安装在服务器上的NewtonSoft.Json库与NuGet在客户端上安装的库不同。这就是服务引用无法重用它的原因。

在这种情况下,只需单击“在指定的引用程序集中重用类型”,检查除了Newtonsoft.Json程序集之外的所有内容并重新生成。

现在,服务参考将无错误地生成。

答案 2 :(得分:0)

您不能直接在 WCF REST 服务中返回类型 JObject 或 JToken,因为您会收到可怕的错误“Type 'Newtonsoft.Json.Linq.JToken' is a recursive collection data contract”。

我通过在返回它们之前将 JSON 对象序列化为 Stream 类型来解决这个问题...

[WebInvoke(Method = "GET",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedResponse,
UriTemplate = "/api/myGetRequest")]
public Stream myFunction(string x, string y)
{ 
  WebOperationContext webcontext = WebOperationContext.Current;
  webcontext.OutgoingResponse.Headers[HttpResponseHeader.ContentType] = "application/json";

  string json = JsonConvert.SerializeObject(myJsonObject, Newtonsoft.Json.Formatting.Indented);`

  return new MemoryStream(Encoding.UTF8.GetBytes(json ?? ""));
}