【问题标题】:Wcf Service Library interface type not being exposedWcf 服务库接口类型未公开
【发布时间】:2015-04-28 03:09:15
【问题描述】:

我已经查看了很多关于我遇到的问题的示例(包括Passing Interface in a WCF Service?),但直到现在还没有找到解决方案。我有一个 Wcf 服务库 (.NET 4.0),其中包含以下内容

public class Service : IService
{
    public bool Ping(IChannelManager channelManager)
    {
        return channelManager.Ping();
    }
}

[ServiceContract]
public interface IService
{
    [OperationContract]
    bool Ping(IChannelManager channelManager);
}

[ServiceContract]
[ServiceKnownType(typeof(TestChannelName))]
public interface IChannelManager
{
    [OperationContract]
    bool Ping();
}

[DataContract]
public class TestChannelName : IChannelManager
{
    public bool Ping()
    {
      //perform a ping
      return true;
    }
}

我的项目编译良好。但是当我尝试从控制台应用程序将其添加为服务参考时,我可以很好地添加它并尝试访问如下方法;

using (Test.ServiceClient oClient = new Test.ServiceClient())
{
     oClient.Ping();
}

但我遇到的问题是 Wcf 服务上的 Ping() 方法,接口类型是对象 channelmanager 吗?喜欢

我尝试将 [ServiceKnownType(typeof(TestChannelName ))] 添加到两个接口,但没有成功。

我哪里错了?

【问题讨论】:

  • 看起来你想要一个神奇的IChannelManager服务契约的服务实现?或者我读错了问题。谁创建了一个 TestChannel 实例并调用了 IService 实现?
  • Service : IService 是我的 Wcf 服务。我有一个我希望能够调用的方法 Ping(),它将根据我通过的 IChannelManager 执行不同的 Ping 测试
  • 你能修复你的客户端示例来显示这个吗?
  • 我更新了我的问题以显示正在显示的对象类型
  • 我猜客户来自 mex 还是 wsdl?

标签: c# wcf interface


【解决方案1】:

我的答案将分为两部分 - 对为什么会发生这种情况的技术概述 - 以及对为什么会发生这种情况的哲学思考。

首先从技术上看:

http://localhost:8733/Design_Time_Addresses/YourProject/Service1/?singlewsdl

从您的示例代码创建的 wsdl 文件,您将找到以下内容:

  <xs:element name="Ping">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" name="channelManager" nillable="true" type="xs:anyType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

通过mex 或如您在上面的wsdl 中看到的那样。你得到xs:anytype(实际上是c#对象)。这种行为虽然令人沮丧,但在意料之中,Mex 和 WsdlExtractor 只了解具体类型 - 在服务参数中由 [DataContract] 表示的 DataMembers,或者是简单类型。任何其他都将被优雅地视为“对象”,而不是仅仅编译失败。

哲学部分:

实际上,您正在尝试将方法 [ServiceContract] 作为参数传递。服务(其逻辑在某些 DLL 中构建到 IL)不会序列化和通过网络传递 - 不是因为它无法完成 - 因为这不是它们的用途。

在您的示例中IChannelManager[ServiceContract],您甚至尝试将Ping() 导出为[OperationContract][ServiceKnownType] 属性并不能解决这个问题。

那么[ServiceKnownType] 什么时候有用?这很好documented 但它的要点是 - 如果您的 DataMember 在运行时要保存一些具体的类 - 编译器无法在编译时推断(例如接口、抽象类或基类)那么反序列化器不会能够猜测在尝试反序列化时应该知道哪些具体类型。

然后你可能会对我说 - 这听起来很公平,但我需要将我的逻辑(服务)作为参数传递。对此我想说 - 你需要的是重新设计你的解决方案。也许编写和托管更多服务并使用StrategyDelegation 模式的等效服务。

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    相关资源
    最近更新 更多