【问题标题】:Operation not supported in the WCF Test ClientWCF 测试客户端不支持的操作
【发布时间】:2012-04-08 11:00:12
【问题描述】:

我创建了一个 WCF 服务,并在主 DataContract 上添加了另一个操作合同到默认服务:

[OperationContract]
void DoSomething(UserData data);

然后我在下面有这样的东西(为了示例的目的而简化了)。问题是,即使层次结构中的所有类都用 DataContract 装饰,并且它们的所有成员都用 DataMember 装饰,但当我使用 WCF 测试客户端时,它有一个红色图标,表示“WCF 测试客户端不支持该操作”。

[DataContract]
public class UserData {
   [DataMember]
   public uint One { get; set; }

   [DataMember]
   public CompositeType Extra { get; set; }

   public UserData() { ctor. code }
}


[DataContract]
public class CompositeType {
    [DataMember]
    public uint Two { get; set; }

    public UserData() { ctor code }
}

【问题讨论】:

  • 我看到两个类同名但一个缺少复合类型,这是什么意思?您还忘记发布复合类型的类。
  • 我看到你在谈论层次结构。您是否正在实施任何类型的递归关系?因为这需要递归使用的类用[DataContract(IsReference=True)]装饰
  • @Silvermind 抱歉拼写错误,第二个(已更正)是 CompositeType 而不是 UserData。我还在主 DataContract 中使用的子类型中添加了 IsReference 参数,但这并没有解决问题。

标签: c# wcf


【解决方案1】:

好的,经过整个过程(感谢所有提示),解决方案是这样的:

  • DataContract 中的 IsReference 属性根本不需要
  • 即使 OperationContract 返回 void,也根本不需要 DataContract 中的 IsOneWay 属性。
  • KnownType 也不需要,前提是层次结构中的所有子类型都是我的,换句话说,由我而不是 .NET 定义并酌情标记为 DataContractDataMember
  • 摆脱OperatingSystem 并构建一个包装器DataContractOperatingSystem 中提取必要的信息解决了这个问题。

现在 WCF 测试客户端中没有错误

【讨论】:

  • 您好,遇到了类似的问题。您所说的“摆脱操作系统并构建一个从操作系统中提取必要信息的包装器 DataContract 解决了这个问题”到底是什么意思。
【解决方案2】:

将属性添加到您的“UserData”类[KnownType(typeof(CompositeType))]

喜欢:

[DataContract]
[KnownType(typeof(CompositeType))]
public class UserData 
{
   [DataMember]
   public uint One { get; set; }

   [DataMember]
   public CompositeType Extra { get; set; }

   public UserData() { ctor. code }
}

http://msdn.microsoft.com/en-us/library/ms730167.aspx

编辑:

http://msdn.microsoft.com/en-us/library/system.operatingsystem.aspx

OperatingSystem 类有一些与其他类相关的属性。您可以在已知类型中包含所有这些类,但依赖链可能会变得相当大,我强烈建议您根本不要使用操作系统类。

您应该从操作系统类中找出您真正需要的信息,并创建您自己的 DTO 以在响应中传回。这样您就可以确保所有类型都可以在您的合同中轻松定义。

【讨论】:

  • 我已将 KnownType 装饰添加到父类型中,以指示在 DataMembers 的返回值中使用的自定义类的类型,对于层次结构下的类也是如此,基本上所有不是本机类型的在 DataContract 中用 [KnownType] 标记。问题依然存在。
  • @LordofScripts 你可以创建一个示例项目并将其上传到某个地方,以便我(和其他人)可以看看。
  • 这是ISampleService.cs
  • 在制作更好的样本的过程中,我发现了罪魁祸首……我在 DataContract 中使用的子类型之一是名为 System.Environment.OperatingSystem 的 .NET 类。当我在数据合同中拥有它时,即使我用 [KnownType(typeof(System.Environment.OperatingSystem))] 进行装饰,我也会收到错误消息。如果我忽略它,那么错误就会消失。那么,如何在 DataContract 中使用这些 .NET 类而不出现错误?
  • @LordofScripts 您只能序列化属性已用 DataMember 属性修饰的成员,因此需要为某些 .Net 类创建包装器。
【解决方案3】:

如果您创建一个测试客户端(如控制台应用程序)并向 wcf 添加服务引用,该服务是否工作?如果是这样,那么您的数据合同可能具有 WCF 测试客户端不支持的那些类型之一。

See this related issue

【讨论】:

【解决方案4】:

WCF 对服务调用的默认期望是请求-响应 - WCF 期望得到某种响应。

如果你想使用void(如:没有返回值),你需要用

装饰那些方法
[OperationContract(IsOneWay = true)]
void DoSomething(UserData data);

告诉 WCF 运行时不要期待调用的任何返回值

在 MSDN 杂志上阅读有关 WCF: Working with One-Way Calls, Callbacks and Events 的更多信息。

【讨论】:

  • 我从来不需要IsOneWay == true 来进行 WCF 合约中的普通绑定,因为双通道可以向客户端发送独立响应,它不是更适合 DualBinding 吗?
  • 您不必设置 IsOneWay = true 并且您应该知道,如果您这样做,客户端将不会收到服务器抛出的任何错误异常,因为它不会等待 void wcf 服务将返回的响应以允许传回错误异常。
  • 这也没有做任何事情,同样的问题。我的操作合同有一个我定义的类型的参数,它用 DataContract 标记。该自定义类型有几个用 DataMember 标记的属性,每个属性都是自定义(但相当简单)类型,所有这些子类型都在其声明中标记为 DataContract。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多