为什么我从OperationContext.Current.GetCallbackChannel<>()获得InvalidCastException

时间:2009-11-27 12:51:11

标签: .net wcf

为了启用对客户端的aysc回调,我需要将Begin / End方法添加到我的服务上定义为CallbackContract的接口。 (我正在使用剪切合同程序集,而不是生成代理类)

[ServiceContract(CallbackContract=typeof(IClient)]
interface IEngineManager

作为第一步,我将IClient接口从共享接口程序集中复制到本地名称空间,而不进行任何其他更改。我希望由于界面逻辑与合同中的相同,WCF将允许它被使用。 但是WCF由于某些原因不喜欢它,为什么?

[ServiceContract]
public interface IClient
{
  [OperationContract(Action = "ReceiveMessage", 
     ReplyAction = "ReceiveMessageResponse")]
  void ReceiveMessage(SimMessage message);
}

//....
// this give the InvalidCastException
var client = OperationContext.Current.GetCallbackChannel<MyNameSpace.IClient>();

但是,如果我只使用共享合同程序集中的原始IClient接口,那一切都有效!

2 个答案:

答案 0 :(得分:2)

作为DxCK siad,传递给OperationContext.Current.GetCallbackChannel <T&gt;()的类型必须与您在服务实现的接口上的[ServiceContract]属性中指定的类型完全相同。< / p>

但是我需要为回调使用不同的接口,所以我可以添加支持aysc回调所需的Begin / End方法。

首先是我的新回调界面。

[ServiceContract]
public interface IClientWithAsyncMethods : IClient
{
  [OperationContract(
    AsyncPattern = true, 
    Action = "ReceiveMessage", 
    ReplyAction = "ReceiveMessageResponse")]
  IAsyncResult BeginReceiveMessage(SimMessage message, 
    AsyncCallback callback, object asyncState);

  void EndReceiveMessage(IAsyncResult asyncResult);
}

然后需要为我的服务定义一个新接口来实现:

[ServiceContract(CallbackContract = typeof(IClientWithAsyncMethods))]
public interface IEngineManagerWithAsyncCallbacks : IEngineManager
{
}

作为CallbackContract重新接受新回调接口的唯一变化,这是正常的,因为IClientWithAsyncMethods是IClient的子类型。

然后最后一步是将服务实现更改为用于服务接口:

  • 更改服务实施的界面类型
  • 将新界面传递到ServiceHost.AddServiceEndpoint()(和/或编辑WCF配置文件)
  • 在对OperationContext.Current.GetCallbackChannel <IClientWithAsyncMethods&gt;()
  • 的调用中使用IClientWithAsyncMethods

其余的只是以正常方式调用aysc方法。

答案 1 :(得分:2)

当您执行GetCallbackChannel时,您应该指定与[ServiceContract]属性中指定的类型完全相同的类型,即强类型。

即使A.IClient和B.IClient具有完全相同的代码而只更改了命名空间,这些类型与.NET的视图完全不同。