无法使KnownType与WCF一起使用

时间:2012-07-03 21:46:14

标签: wcf known-types

我有一个接口和一个在不同程序集中定义的类,如下所示:

namespace DataInterfaces
{
    public interface IPerson
    {
        string Name { get; set; }
    }
}

namespace DataObjects
{
    [DataContract]
    [KnownType( typeof( IPerson ) ) ]
    public class Person : IPerson
    {
        [DataMember]
        public string Name { get; set; }
    }
}

这是我的服务界面:

public interface ICalculator
{
    [OperationContract]
    IPerson GetPerson ( );
}

当我更新我的客户服务参考时,我会在Reference.cs中找到它:

public object GetPerson() {
    return base.Channel.GetPerson();

我希望KnownType会在这里给我IPerson而不是“object”。

我也试过[KnownType( typeof( Person ) ) ]同样的结果。我控制了客户端和服务器,所以我在两个地方都有我的DataObjects(定义了Person)和DataInterfaces(其中定义了IPerson)程序集。有什么明显的东西我不见了吗?我认为KnownType是能够使用WCF接口的答案。

-----更多信息----- 我从Person类中删除了KnownType并添加了

[ServiceKnownType( typeof( Person ) ) ]

到我的服务界面,正如理查德所建议的那样。客户端代理看起来仍然相同,

public object GetPerson() { return base.Channel.GetPerson();

,但现在它没有爆炸。但是,客户端只有一个“对象”,因此必须先将它转换为IPerson才能使用。

        var person = client.GetPerson ( );
        Console.WriteLine ( ( ( IPerson ) person ).Name );

3 个答案:

答案 0 :(得分:1)

如果您需要服务合同上的[ServiceKnownType],那么IPerson程序集不需要了解Person程序集。

[ServiceKnownType(typeof(Person))]
public interface ICalculator
{
    [OperationContract]
    IPerson GetPerson ( );
}

或者,您可以使用KnownType constructor that takes a method name的版本。然后,这可以从配置文件

中找到已知类型

但是,我不明白为什么你在合同上使用接口。合同是传递的消息的定义 - 在这种情况下接口如何帮助?

答案 1 :(得分:0)

你需要在IPerson上放置KnownType而不是像这样的人:

[KnownType(typeof(Person))]
public interface IPerson
{
    string Name { get; set; }
}

答案 2 :(得分:0)

继承的整个想法是基类不了解专门的类。使用专用类型装饰数据契约基类(通常在常见的dll中定义)似乎打破了基本的OOD原则? IMHO SvcUtil应该为您完成这项工作,并在生成代理时使用已知类型。似乎当svcutil被开发时,甚至没有考虑基本的OO。