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();
}
}
很好的回答!非常感谢你! – Kyle