我有一个接口和一个在不同程序集中定义的类,如下所示:
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 );
答案 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。