C# WCF:在回调中使用自定义类
我已经设法让WCF回调(通过命名管道)处理字符串,但遗憾的是,我无法让它处理自定义类 以下是服务声明+实现: 这是我的数据合同: 以下是我在客户端所做的工作: 当我改变C# WCF:在回调中使用自定义类,c#,.net,wcf,callback,C#,.net,Wcf,Callback,我已经设法让WCF回调(通过命名管道)处理字符串,但遗憾的是,我无法让它处理自定义类 以下是服务声明+实现: 这是我的数据合同: 以下是我在客户端所做的工作: 当我改变 public void Send() { try { channel.OnCallback("I love deadlines. I like the whooshing sound they make as they fly by.");
public void Send()
{
try
{
channel.OnCallback("I love deadlines. I like the whooshing sound they make as they fly by.");
}
catch (Exception ex)
{
Form1.AddText(ex.GetType() + "|" + ex.Message);
}
}
到
调用回调方法时,我在服务器上遇到以下异常(请参见上文):
但是,我已经将KnownTypeAttribute应用于WCF服务实现。一般来说,无论是谁(服务器还是客户端)正在反序列化参数或返回值,都需要知道在运行时需要什么类型(更确切地说,是什么契约)才能这样做。在这种情况下,类型为object
的已声明参数不能为客户机提供足够的信息来反序列化服务器可能发送回它的任何内容。将其替换为类型(如果服务器计划在回调中发送子类实例,则用[KnownType]
修饰)可以解决此问题
您还可以使用告知DataContractSerializer已知的类型,但这是应用程序范围内的,对我来说似乎有点生硬
我曾经有过一个不太清楚的案例,我的合同是这样的:
[ServiceContract]
interface ISearch
{
[OperationContract]
SearchResult Search(SearchQuery query);
}
[DataContract]
[KnownType(typeof(Subclass1InSharedAssembly)), etc...]
class SearchResult
{
[DataMember]
BaseClassDeclaredInSharedAssembly Value { get; set; }
}
因为我希望服务器和客户机使用(有用的)共享程序集类型,所以我在这两种类型中都引用了共享程序集,并选择不为它们生成任何代理类型。。。因此,svcutil
没有为我生成任何KnownTypeAttribute
s。部分课程拯救了我;在客户端上,您可以执行以下操作:
// generated proxy .cs
[DataContract]
partial class SearchResult
{
...
}
// hand-written .cs
[KnownType(typeof(Subclass1InSharedAssembly)), etc.]
partial class SearchResult
{
// Now the client knows how to deserialise derived types.
}
您是在客户端还是服务器上收到异常?生成的客户端代码中是否包含
KnownTypeAttribute
?在服务器上引发异常。我在ClientClass
中添加了KnownTypeAttribute,之后发现:)基本问题是在回调契约中使用object
作为参数类型。客户端不知道如何反序列化自定义类型,因此必须在某个地方输入KnownTypeAttribute
@yas4891,你最后是怎么解决的?您现在是否有标记为DataContract
-和KnownType
-的参数类型?我将object
更改为TransmissionClass
,并将KnownType
应用于实现客户端界面的类。请写一个答案,你将因此获得学分
[ServiceContract]
interface ISearch
{
[OperationContract]
SearchResult Search(SearchQuery query);
}
[DataContract]
[KnownType(typeof(Subclass1InSharedAssembly)), etc...]
class SearchResult
{
[DataMember]
BaseClassDeclaredInSharedAssembly Value { get; set; }
}
// generated proxy .cs
[DataContract]
partial class SearchResult
{
...
}
// hand-written .cs
[KnownType(typeof(Subclass1InSharedAssembly)), etc.]
partial class SearchResult
{
// Now the client knows how to deserialise derived types.
}