Как добавить заголовок HTTP-запроса в запросы Silverlight RIA? - PullRequest
1 голос
/ 08 декабря 2011

Мне нужно передать HTTP-заголовок для каждого запроса службы RIA, выполняемого из приложения Silverlight. Значение заголовка должно исходить от экземпляра приложения, а не от файла cookie. Я знаю, что этого можно достичь, поместив его в DTO, но это не вариант, потому что многие наши сервисные вызовы используют сущности и наборы изменений, поэтому нет базового класса, к которому можно было бы присоединиться для всех запросов. Поэтому я ищу централизованное и безопасное средство передачи чего-либо с каждым запросом, чтобы разработчикам не приходилось с этим беспокоиться. Пользовательский заголовок HTTP будет работать нормально, но я не знаю, как перехватить исходящий запрос, чтобы установить его.

У кого-нибудь есть идеи, которые я могу попробовать?

1 Ответ

3 голосов
/ 09 декабря 2011

На нижнем уровне вы можете добавить HTTP-заголовки с помощью IClientMessageInspector. Попробуйте начать с этого поста на форуме SL .

Следующий шаг зависит от ваших вариантов использования.

Если значение заголовка должно быть одинаковым для любого метода, вызываемого DomainContext, тогда вы можете просто расширить контекст, используя частичный класс, добавить свойство для значения заголовка и использовать это свойство в инспекторе.

Если вам нужно передавать разные значения для каждого вызова метода, вам, вероятно, нужно заключить ваш DomainContext в другой класс и добавить аргумент для каждого метода контекста, который примет значение заголовка и передаст его инспектор как-то. Излишне говорить, что без генератора кода это было бы сложно.

Вот адаптированный пример с форума SL для первого случая:

public sealed partial class MyDomainContext
{
  public string HeaderValue { get; set; }

  partial void OnCreated()
  {
    WebDomainClient<IMyDomainServiceContract> webDomainClient = (WebDomainClient<IMyDomainServiceContract>)DomainClient;
    CustomHeaderEndpointBehavior customHeaderEndpointBehavior = new CustomHeaderEndpointBehavior(this);
    webDomainClient.ChannelFactory.Endpoint.Behaviors.Add(customHeaderEndpointBehavior);
  }
}

public class CustomHeaderEndpointBehavior : IEndpointBehavior
{
  MyDomainContext _Ctx;

  public CustomHeaderEndpointBehavior(MyDomainContext ctx)
  {
    this._Ctx = ctx;
  }      

  public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
  public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
  {
    clientRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(this._Ctx));
  }
  public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) { }
  public void Validate(ServiceEndpoint endpoint) { }
}

public class CustomHeaderMessageInspector : IClientMessageInspector
{
  MyDomainContext _Ctx;

  public CustomHeaderMessageInspector(MyDomainContext ctx)
  {
    this._Ctx = ctx;
  }

  public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) {}
  public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
  {
    string myHeaderName = "X-Foo-Bar";
    string myheaderValue = this._Ctx.HeaderValue;

    HttpRequestMessageProperty property = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
    property.Headers[myHeaderName] = myheaderValue;
    return null;
  }
}
...