2015-07-24 3 views
2

У меня есть интерфейс IClientMessageInspector с реализованным методом BeforeSendRequest(). В этом методе я хочу получить объект Session, установленный на клиенте. Что-то вроде.WCF собственный клиент EndpointBehavior читает сеанс

public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    { 
     //Instantiate new HeaderObject with values from ClientContext; 
     var dataToSend = new MyCustomHeader 
      { 
       MyValue = HowDoIGetClientSession["abcValue"]; 
      }; 

     var typedHeader = new MessageHeader<CustomHeader>(dataToSend); 
     var untypedHeader = typedHeader.GetUntypedHeader("custom-header", "s"); 

     request.Headers.Add(untypedHeader); 
     return null; 
    } 

Я думаю, что нужно что-то очень похожее, как в this question.

+0

проверьте, есть ли у вас внутри объекта HttpContext. –

+0

Вы имеете в виду тело метода 'BeforeSendRequest'? У меня нет или я не знаю, как это прочитать. 'HttpContext.Current' имеет значение NULL. – DDan

+0

для 'WCF' Я думаю, что это' OperationContext'. –

ответ

0

В итоге я использовал подход, как в this tutorial. Я добавляю соответствующую информацию в cookie как пары ключ-значение и читаю ее в реализации службы. Вместо ссылки на службу я использую ChannelFactory, но в основном основная идея такая же, как в учебнике.

Мой BeforeSendRequest метод:

 public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, 
      System.ServiceModel.IClientChannel channel) 
     { 
      HttpRequestMessageProperty httpRequestMessage; 
      object httpRequestMessageObject; 
      if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name 
       , out httpRequestMessageObject)) 
      { 
       httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty; 
       if (string.IsNullOrEmpty(httpRequestMessage.Headers["Cookie"])) 
       { 
        httpRequestMessage.Headers["Cookie"] = cookie; 
       } 
      } 
      else 
      { 
       httpRequestMessage = new HttpRequestMessageProperty(); 
       httpRequestMessage.Headers.Add("Cookie", cookie); 
       request.Properties.Add(HttpRequestMessageProperty.Name 
        , httpRequestMessage); 
      } 

      return null; 
     } 

связывания параметров является:

  <basicHttpBinding> 
       <binding name="basicHttp" closeTimeout="00:01:00" 
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferPoolSize="20000000" maxBufferSize="20000000" maxReceivedMessageSize="20000000" 
        textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" 
        messageEncoding="Text"> 
        <readerQuotas maxDepth="32" maxStringContentLength="200000000" maxArrayLength="200000000" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <security mode="None"> 
         <transport clientCredentialType="None" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="UserName" algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </basicHttpBinding> 

В клиентском приложении мне нужно (в web.configsystem.serviceModel):

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/> 

И в аннотация для класса реализации службы:

[AspNetCompatibilityRequirements(RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Required)] 
    public class MyService : IMyService { 
     // ... 
    } 

Для обслуживания вызовов Я использую объект-оболочку, которая реализует IDisposable, берет случай надлежащей утилизации и добавив к EndpointBehaior в ChannelFactory перед созданием канала.

_factory = new ChannelFactory<T>(); 
    _factory.Endpoint.Behaviors.Add(new CookieEndpointBehavior(cookieStr)); 
    _channel = _factory.CreateChannel(); 

Я использую класс обертку службы в using block, который будет вызывать Dispose после того, как она выходит из области видимости.

0

Если ваше клиентское приложение и служба WCF размещены в одном приложении (фактически виртуальном приложении в IIS), вы можете поделиться своим состоянием сеанса.

Но вам нужно включить режим Compability ASP.Net в пределах вашего WCF (см это: https://msdn.microsoft.com/en-us/library/ms752234.aspx)

Если приложения размещаются в различных приложениях, вы можете сделать это, но вы должны использовать внешнее запоминающее устройство для вы, как сервер состояния сеанса (см. здесь: https://msdn.microsoft.com/en-us/library/ms178586%28v=vs.140%29.aspx).

Вы выполняете то же самое, но вы должны установить в обоих файлах web.config одно и то же хранилище сеансов.

Надеюсь, это поможет.

Смежные вопросы