2012-04-30 39 views
7

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

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

但我一直没能想出一个办法来修改一个WebChannelFactory头。

回答

10

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<T>的类是一种简单的方法。下面的代码是这个问题的完整示例,其中包含两个选项(直接使用作用域,使用基于客户端的类),用于在来自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(); 
    } 
} 
+0

很好的回答!非常感谢你! – Kyle