如何将HTTP请求标头添加到Silverlight RIA请求

时间:2011-12-08 16:36:47

标签: silverlight http-headers ria

我需要为每个从Silverlight应用程序发出的RIA服务请求传递HTTP标头。标头的值需要来自app实例,而不是来自cookie。我知道这可以通过将它放在DTO中来实现,但它不是一个选项,因为我们的许多服务调用使用实体和更改集,因此没有基类可以用于所有请求。所以我正在寻找一种集中且安全的方法来将每个请求传回去,这样开发人员就不用担心了。自定义HTTP标头可以正常工作,但我不知道如何拦截出站请求来设置它。

任何人都有我可以尝试的想法吗?

1 个答案:

答案 0 :(得分:3)

在较低级别,您可以在IClientMessageInspector的帮助下添加HTTP标头。尝试从this post on SL forum开始。

下一步取决于您的使用案例。

如果DomainContext调用的任何方法的标头值必须相同,那么您可以使用partial class扩展上下文,为标头值添加属性并在检查器中使用该属性。

如果需要为每个方法调用传递不同的值,您可能需要将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;
  }
}