【问题标题】:WebChannelFactory & Headers?WebChannelFactory 和标头?
【发布时间】:2012-05-10 10:50:12
【问题描述】:

是否可以在WebChannelFactory 上设置标题?如果我使用 WebClient 对象,我可以这样做:

WebClient client = new WebClient();
client.Headers.Add("referer", "http://stackoverflow.com");
client.Headers.Add("user-agent", "Mozilla/5.0");

但我还没有找到修改WebChannelFactory 上的标头的方法。

【问题讨论】:

    标签: c# wcf webclient webchannelfactory


    【解决方案1】:

    WebChannelFactory 类本身不采用任何 HTTP 标头,但您可以将它们添加到当前的 WebOperationContext 中,前提是您为其创建了一个新作用域 - 见下文。

    WebChannelFactory<ICalculator> factory = new WebChannelFactory<ICalculator>(new Uri(baseAddress));
    ICalculator proxy = factory.CreateChannel();
    using (new OperationContextScope((IContextChannel)proxy))
    {
        WebOperationContext.Current.OutgoingRequest.Headers.Add("referer", "http://stackoverflow.com");
        WebOperationContext.Current.OutgoingRequest.Headers.Add("user-agent", "Mozilla/5.0");
        Console.WriteLine("Add: {0}", proxy.Add(33, 55));
        Console.WriteLine();
    }
    
    using (new OperationContextScope((IContextChannel)proxy))
    {
        WebOperationContext.Current.OutgoingRequest.Headers.Add("referer", "http://stackoverflow.com");
        WebOperationContext.Current.OutgoingRequest.Headers.Add("user-agent", "Mozilla/5.0");
        Console.WriteLine("Subtract: {0}", proxy.Subtract(44, 33));
        Console.WriteLine();
    }
    

    这可行,但它相当冗长 - 如果您想向其中添加传出标头,您基本上需要为每个调用创建一个新范围。

    另一种选择是将客户端包装在客户端类中,以便为您添加范围和标头。使用从ClientBase&lt;T&gt; 派生的类是一种简单的方法。下面的代码是这个问题的完整示例,有两个选项(直接使用范围,使用客户端基派生类)用于在来自WebChannelFactory 创建的代理的请求中添加 HTTP 标头。

    public class StackOverflow_10388746
    {
        [ServiceContract]
        public interface ICalculator
        {
            [WebGet]
            int Add(int x, int y);
            [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
            int Subtract(int x, int y);
        }
        public class Service : ICalculator
        {
            public int Add(int x, int y)
            {
                PrintHeaders("Add");
                return x + y;
            }
            public int Subtract(int x, int y)
            {
                PrintHeaders("Subtract");
                return x - y;
            }
            void PrintHeaders(string operation)
            {
                Console.WriteLine("Incoming HTTP headers for operation '{0}'", operation);
                foreach (var header in WebOperationContext.Current.IncomingRequest.Headers.AllKeys)
                {
                    Console.WriteLine("  {0}: {1}", header, WebOperationContext.Current.IncomingRequest.Headers[header]);
                }
            }
        }
        public class MyWebClient : ClientBase<ICalculator>, ICalculator
        {
            Dictionary<string, string> outgoingHeaders = new Dictionary<string, string>();
    
            public MyWebClient(Uri baseAddress)
                : base(new WebHttpBinding(), new EndpointAddress(baseAddress))
            {
                this.Endpoint.Behaviors.Add(new WebHttpBehavior());
            }
    
            #region ICalculator Members
    
            public int Add(int x, int y)
            {
                using (new OperationContextScope(this.InnerChannel))
                {
                    foreach (var headerName in this.outgoingHeaders.Keys)
                    {
                        WebOperationContext.Current.OutgoingRequest.Headers.Add(headerName, this.outgoingHeaders[headerName]);
                    }
    
                    this.outgoingHeaders.Clear();
                    return this.Channel.Add(x, y);
                }
            }
    
            public int Subtract(int x, int y)
            {
                using (new OperationContextScope(this.InnerChannel))
                {
                    foreach (var headerName in this.outgoingHeaders.Keys)
                    {
                        WebOperationContext.Current.OutgoingRequest.Headers.Add(headerName, this.outgoingHeaders[headerName]);
                    }
    
                    this.outgoingHeaders.Clear();
                    return this.Channel.Subtract(x, y);
                }
            }
    
            #endregion
    
            public void AddOutgoingHeader(string name, string value)
            {
                this.outgoingHeaders.Add(name, value);
            }
        }
    
        public static void Test()
        {
            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
            WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
            host.Open();
            Console.WriteLine("Host opened");
    
            WebChannelFactory<ICalculator> factory = new WebChannelFactory<ICalculator>(new Uri(baseAddress));
            ICalculator proxy = factory.CreateChannel();
            using (new OperationContextScope((IContextChannel)proxy))
            {
                WebOperationContext.Current.OutgoingRequest.Headers.Add("referer", "http://stackoverflow.com");
                WebOperationContext.Current.OutgoingRequest.Headers.Add("user-agent", "Mozilla/5.0");
                Console.WriteLine("Add: {0}", proxy.Add(33, 55));
                Console.WriteLine();
            }
    
            using (new OperationContextScope((IContextChannel)proxy))
            {
                WebOperationContext.Current.OutgoingRequest.Headers.Add("referer", "http://stackoverflow.com");
                WebOperationContext.Current.OutgoingRequest.Headers.Add("user-agent", "Mozilla/5.0");
                Console.WriteLine("Subtract: {0}", proxy.Subtract(44, 33));
                Console.WriteLine();
            }
    
            MyWebClient client = new MyWebClient(new Uri(baseAddress));
            client.AddOutgoingHeader("referer", "http://stackoverflow.com");
            client.AddOutgoingHeader("user-agent", "Mozilla/5.0");
            Console.WriteLine("Add (via client): {0}", client.Add(44, 77));
            Console.WriteLine();
    
            client.AddOutgoingHeader("referer", "http://stackoverflow.com/another");
            client.AddOutgoingHeader("user-agent", "Mozilla/5.0-b");
            Console.WriteLine("Add (via client): {0}", client.Subtract(44, 77));
            Console.WriteLine();
    
            Console.Write("Press ENTER to close the host");
            Console.ReadLine();
            host.Close();
        }
    }
    

    【讨论】:

    • 很好的答案!非常感谢!
    猜你喜欢
    • 2012-05-13
    • 1970-01-01
    • 2012-05-11
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 2011-08-10
    • 2012-09-18
    相关资源
    最近更新 更多