我们有一个使用 WCF 服务的 ASP.NET Web 应用程序。目前的系统结构如下:
In AjaxWebService.svc.cs:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
[ServiceContract(Namespace = "", SessionMode = SessionMode.Allowed)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
private Service m_Service;
private Service Service
{
get
{
if (m_Service == null)
{
m_Service = new Service();
}
return m_Service;
}
}
[OperationContract]
internal Users[] getUsers()
{
return this.Service.getUsers();
}
[OperationContract]
internal products[] getproducts()
{
return this.Service.getproducts();
}
In Service.cs:
private IServiceClient m_ServiceGateway;
private IServiceClient ServiceGateway
{
get
{
if (m_ServiceGateway == null)
{
m_ServiceGateway = new IServiceClient();
}
return m_ServiceGateway;
}
}
internal Users[] getUsers()
{
return this.ServiceGateway.getUsers(this.RoleId, this.Token);
}
internal products[] getproducts()
{
return this.ServiceGateway.getproducts(this.RoleId, this.Token);
}
In IServiceGateway.cs:
[OperationContract]
List<getUsers> getUsers(int RoleId, string Token);
[OperationContract]
List<products> getProducts(int RoleId, string Token);
问题: 我想将自定义 HTTP 标头(如 User-Agent 和 Accept)传递给 WCF 服务调用,而不更改现有方法签名(例如,返回 this.ServiceGateway.getUsers(this.RoleId, this.Token); 并返回 this.ServiceGateway。 getproducts(this.RoleId, this.Token);).
我尝试在 ServiceGateway 属性中初始化并传递标头,如下所示:
private IServiceClient m_ServiceGateway;
private IServiceClient ServiceGateway
{
get
{
if (m_ServiceGateway == null)
{
m_ServiceGateway = new IServiceClient();
using (new OperationContextScope(m_ServiceGateway.InnerChannel))
{
// Set HTTP headers
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers["User-Agent"] = "mrt/1.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)";
httpRequestProperty.Headers["Accept"] = "application/json";
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
}
}
return m_ServiceGateway;
}
}
但是,标头未正确传递到 WCF 服务。
问题: 有没有办法将这些标头传递给 WCF 服务,而不更改现有的方法调用,例如 return this.ServiceGateway.getUsers(this.RoleId, this.Token);?如何在不修改每个 API 的情况下将自定义标头集中应用到所有 WCF 服务调用?
您可以创建
CustomMessageInspector
来实现此功能。 这里是相关帖子,你可以先查看一下。
自定义消息检查器.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.Web;
namespace WcfHeaderDemo
{
public class CustomMessageInspector : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
HttpRequestMessageProperty httpRequestMessage;
if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
{
httpRequestMessage = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
}
else
{
httpRequestMessage = new HttpRequestMessageProperty();
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
// Add custom header here
httpRequestMessage.Headers["User-Agent"] = "mrt/1.0";
httpRequestMessage.Headers["Accept"] = "application/json";
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
}
}
自定义端点行为.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Web;
namespace WcfHeaderDemo
{
public class CustomEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new CustomMessageInspector());
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint endpoint) { }
}
}
使用它
ServiceHost host = new ServiceHost(/* Parameters */);
host.Description.Behaviors.Add(/* Service Behavior */);
相关文档: