WCF使用接口作为参数调用服务方法会导致SocketException错误。

3

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

bool GetFoo(out IFoo foo)
{
    foo = new AFoo();
    return true;
}

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

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

System.ServiceModel.CommunicationException:'在接收来自http://localhost:4504/MyService 的 HTTP 响应时发生错误。这可能是因为服务端点绑定未使用 HTTP 协议。这也可能是由于服务器中止了 HTTP 请求上下文(可能是由于服务关闭)。有关更多详细信息,请参见服务器日志.'

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

bool GetFoo()
{
    IFoo foo = new AFoo();
    return true;
}

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


更新1

添加一个基类Foo,使得Afoo继承自Foo,而Foo则从IFoo继承。 例如:AFoo : Foo : IFoo(逻辑上)当服务方法被修改时会出现相同的错误

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 属性装饰? - Chetan
输出不是问题。为什么呢?因为我的所有服务方法都有输出参数,并且它们可以正常工作。另外,正如我所说,AFoo已经是一个已知类型。 - Gagan
3个回答

1

请看另一个问题:DataContract和继承?

似乎您需要在基类上使用子类的KnownType来完成这种操作,并且当然还需要将它们都放在DataContract下。


感谢@Kevin,这是目前为止对我有效的解决方案,虽然这不是一个完美的解决方案,因为它要求我拥有一个基类来实现继承,但我想使用接口实现。我将在答案中说明如何使其工作。 - Gagan

0

我看到这个问题是因为该类型包含对未标记有DataContract属性的enum类型的引用。你看到的错误很可能掩盖了像这样的内部错误。有时,您可以通过转到调试 -> 异常并打开“在所有抛出的异常上中断”来捕获这些异常。


我甚至尝试从类AFoo和接口IFoo中删除所有属性,但结果相同。 - Gagan

0
解决方案

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

最终我弄好了,并且现在我来分享一下我的做法。简而言之,我忘记在DataContract里添加KnownType了。

首先,我必须像问题部分所描述的那样添加一个基类Foo。接着,我还需要给所有子(派生)类添加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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接