如何在现有项目中将 HTTP 标头传递给来自 AjaxWebService(启用 Ajax)的 WCF 服务调用?

问题描述 投票:0回答:1

我们有一个使用 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 服务调用?

javascript asp.net ajax wcf http-headers
1个回答
0
投票

您可以创建

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 */); 

相关文档:

使用行为配置和扩展运行时 - 服务行为

© www.soinside.com 2019 - 2024. All rights reserved.