svcutil从生成的接口代理中省略ServiceKnownType属性

时间:2009-04-03 07:18:47

标签: wcf svcutil.exe

当我尝试从MSDN实现ServiceKnownType示例时遇到了问题。 在示例中,它们提供以下类:

[DataContract()]
public class Widget
{
    [DataMember]
    public string Id;
    [DataMember]
    public string Catalog;
}

[DataContract()]
public class Machine : Widget
{
    [DataMember]
    public string Maker;
}

以下界面:

[ServiceKnownType(typeof(Widget))]
[ServiceKnownType(typeof(Machine))]
[ServiceContract()]
public interface ICatalog
{
    [OperationContract]
    Hashtable GetItems();
}

问题是当生成代理类时(使用“添加服务引用”/ svcutil.exe),ICatalog代理接口中省略了“ServiceKnownType”属性,导致异常 “格式化程序在尝试反序列化消息时抛出异常:... 将与“Widget”对应的类型添加到已知类型列表中“ 要解决此问题,我必须手动将服务已知属性添加到生成的代理接口,这是一个非常糟糕的解决方案,因为在更新引用时代码会重新生成。 在所有这些情况下,有趣的是,如果GetItems操作将返回对象而不是Hashtable,或者将对象作为参数,则问题将得到解决,即

[OperationContract]
object GetItems();

[OperationContract]
Hashtable GetItems(object obj);

导致ICatalog代理接口上存在“ServiceKnownType”属性。 有谁知道如何解决这个问题?

谢谢

3 个答案:

答案 0 :(得分:1)

我今天花了几个小时来讨论完全相同的问题。我的解决方案是使用IDesign的ServiceModelEx库中的AddGenericResolver方法。

注意:在使用DataContractResolver

时需要.NET 4.0

您可以在IDesign Downloads page找到它。

在我的案例中,我只需添加以下代码行:

Client.AddGenericResolver( typeof ( K2Source ) );

我希望这可以帮助别人在那里拯救几个小时!

您可以在Juval Lowy的“编程WCF服务:掌握WCF和Azure AppFabric服务总线”一书中找到更多信息

答案 1 :(得分:0)

似乎是相关的problem

您是否尝试返回Widgets的通用词典并将[KnownType(typeof(Machine))]放在Widget类上?

答案 2 :(得分:0)

svcutil忽略ServiceKnownType的问题仍然存在。我的解决方案是添加"已知类型"以编程方式提交客户合同:

var client = new ServiceReferenceClient("clientEndpoint");
foreach (var o in client.Endpoint.Contract.Operations)
{
   o.KnownTypes.Add(typeof(MyType01));
   o.KnownTypes.Add(typeof(MyType02));
   o.KnownTypes.Add(typeof(MyType03));
}

这不是完美的解决方案(必须在客户端进行硬编码),但它适用于我。