Почему я получаю InvalidCastException от OperationContext.Current.GetCallbackChannel <> () - PullRequest
1 голос
/ 27 ноября 2009

Чтобы включить обратные вызовы 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 ]

2 голосов
/ 28 ноября 2009

Когда вы выполняете GetCallbackChannel, вы должны указать точно такой же тип, какой вы указали в атрибуте [ServiceContract], он строго типизирован.

Даже если A.IClient и B.IClient имеют одинаковый код с измененным только пространством имен, это совершенно разные типы с точки зрения .NET.

2 голосов
/ 27 ноября 2009

Как и DxCK, тип, передаваемый в OperationContext.Current.GetCallbackChannel <T> (), должен быть точно такого же типа, который вы указали в атрибуте [ServiceContract] интерфейса, который реализует служба.

Однако мне нужно использовать другой интерфейс для обратных вызовов, чтобы я мог добавить методы Begin / End, необходимые для поддержки обратных вызовов aysc.

Итак, во-первых, мой новый интерфейс обратного вызова.

[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.

Затем последним шагом является изменение используемой реализации serve на интерфейс службы:

  • Изменить тип интерфейса, который реализует служба
  • Передать новый интерфейс в ServiceHost.AddServiceEndpoint () (и / или отредактировать файлы конфигурации WCF)
  • Использование IClientWithAsyncMethods при вызове OperationContext.Current.GetCallbackChannel <IClientWithAsyncMethods> ()

Остальное просто вызывает метод aysc обычным способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...