WCF 调用带有接口参数的服务方法导致 SocketException

Posted

技术标签:

【中文标题】WCF 调用带有接口参数的服务方法导致 SocketException【英文标题】:WCF calling service method with an Interface argument results in SocketException 【发布时间】:2018-07-17 19:05:25 【问题描述】:

我有一个 WCF 服务,我在其中实现了一个服务方法,其输出参数的类型是这样的接口

bool GetFoo(out IFoo foo)

    foo = new AFoo();
    return true;

这里IFoo是接口,AFoo是继承的具体类型。

然后在客户端我使用服务引用调用此方法并收到以下错误

System.ServiceModel.CommunicationException: '发生错误时 接收到 HTTP 响应 http://localhost:4504/MyService。这可能是由于 服务端点绑定不使用 HTTP 协议。这也可以 是由于服务器中止了 HTTP 请求上下文 (可能是由于服务关闭)。查看服务器日志了解更多信息 详细信息。'

有趣的是,当我从服务方法中删除接口参数时,一切正常。例如

bool GetFoo()

    IFoo foo = new AFoo();
    return true;

AFoo类型在Client端已经是已知类型,可以正常使用。


更新 1

添加 基类 Foo 使得 Afoo 继承自 Foo 并且 Foo 继承自 IFoo ex: AFoo : Foo : IFoo (逻辑上) 有 same error 当服务方法被修改为

bool GetFoo(out Foo foo)

    foo = new AFoo();
    return true;

我再次将所有类和接口留空(这意味着它们里面什么都没有)


更新 2

以下似乎工作得很好

bool GetFoo(out AFoo foo)

    foo = new AFoo();
    return true;

为什么基类 Foo 不起作用?有什么想法吗?

【问题讨论】:

您是否尝试删除 out ? AFoo 类是否用 DataContract 属性修饰? 输出不是问题。为什么,因为我所有的服务方法都有参数并且工作正常。同样正如我所说,AFoo 已经是一种已知类型。 【参考方案1】:

看看另一个问题:DataContract and inheritance?

看来你需要用子类的KnownType来装饰基类来做这种事情,当然它们都在DataContract下。

【讨论】:

谢谢@Kevin,到目前为止,这对我有用,这不是一个合适的解决方案,因为尽管我想使用接口实现,但这需要我有一个用于继承的基类。我将添加一个关于我如何使它工作的答案。【参考方案2】:

我看到这个是因为该类型包含对未标记DataContract 属性的enum 类型的引用。您看到的错误很可能隐藏了这样的内部错误。有时您可以通过转到 Debug -> Exceptions 并打开“break on all throwed exceptions”来捕获这些问题。

【讨论】:

我什至尝试从 Class AFoo 和接口 IFoo 中删除所有属性,结果相同【参考方案3】:

解决方法

注意:这不是答案,因为它强制创建一个基类。

我终于让它工作了,我将分享我所做的。简而言之,我错过了 DataContract 中的 KnownType

首先,我必须添加一个基类 Foo,如问题部分所述。接下来我有 为所有 Child(inherited) 类添加 KnownType 属性,在我的例子中它只是 AFoo

这是代码的样子

public interface IFoo



[DataContract]
[KnownType(typeof(AFoo))]
public class Foo : IFoo
 // this is the Base Class


public class AFoo : Foo


现在服务方法是这样的

bool GetFoo(out Foo foo)

    foo = new AFoo();
    return true;

一切都好!!

如果可以有如下服务方法(不需要基类),那就太好了

bool GetFoo(out IFoo foo)

    foo = new AFoo();
    return true;

【讨论】:

以上是关于WCF 调用带有接口参数的服务方法导致 SocketException的主要内容,如果未能解决你的问题,请参考以下文章

Python之Suds库调用WCF实现复杂参数序列化

带有参数的 Wcf Restful 服务发布用户名

Wcf 方法接口作为参数在客户端被视为对象

动态调用WCF服务

动态调用WCF服务

在 WCF 中使用 Unity 将依赖项注入到属性中