如何为使用 Axis 1.4 Web 服务的 C# Web 服务客户端添加自定义 Http 标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/897782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add custom Http Header for C# Web Service Client consuming Axis 1.4 Web service
提问by UmutKa
I'm trying to write a web service client in c# which the webservice is Java Axis 1.4. Axis service requires the Authorization: Basic Base64EncodedTokenheader value in the HTTP Headers. I can't find a way to set this header in standart ways of consuming web services in visual studio.net, like normal WSDL generated refernce nor with WSE3.0
我正在尝试用 c# 编写一个 web 服务客户端,其中 web 服务是 Java Axis 1.4。Axis 服务需要HTTP 标头中的Authorization: Basic Base64EncodedToken标头值。我找不到在 Visual Studio.net 中以标准方式使用 Web 服务来设置此标头的方法,例如普通的 WSDL 生成的引用或 WSE3.0
I can't use WCF as the project is developed using .net 2.0.
我无法使用 WCF,因为该项目是使用 .net 2.0 开发的。
Is there any way to do this ?
有没有办法做到这一点?
回答by John Hunter
If you want to send a custom HTTP Header (not a SOAP Header) then you need to use the HttpWebRequest class the code would look like:
如果要发送自定义 HTTP 标头(不是 SOAP 标头),则需要使用 HttpWebRequest 类,代码如下所示:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("Authorization", token);
You cannot add HTTP headers using the visual studio generated proxy, which can be a real pain.
您无法使用 Visual Studio 生成的代理添加 HTTP 标头,这真的很痛苦。
回答by Simon RC
Are we talking WCF here? I had issues where the service calls were not adding the http authorization headers, wrapping any calls into this statement fixed my issue.
我们是在谈论 WCF 吗?我遇到了服务调用未添加 http 授权标头的问题,将任何调用包装到此语句中解决了我的问题。
using (OperationContextScope scope = new OperationContextScope(RefundClient.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " +
Convert.ToBase64String(Encoding.ASCII.GetBytes(RefundClient.ClientCredentials.UserName.UserName + ":" +
RefundClient.ClientCredentials.UserName.Password));
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
PaymentResponse = RefundClient.Payment(PaymentRequest);
}
This was running SOAP calls to IBM ESB via .NET with basic auth over http or https.
这是通过 .NET 运行对 IBM ESB 的 SOAP 调用,并通过 http 或 https 进行基本身份验证。
I hope this helps someone out because I had massive issues finding a solution online.
我希望这对某人有所帮助,因为我在网上寻找解决方案时遇到了很多问题。
回答by user334291
It seems the original author has found their solution, but for anyone else who gets here looking to add actual custom headers, if you have access to mod the generated Protocol code you can override GetWebRequest
:
似乎原作者已经找到了他们的解决方案,但是对于其他任何想要添加实际自定义标头的人来说,如果您有权访问 mod 生成的协议代码,您可以覆盖GetWebRequest
:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.WebRequest request = base.GetWebRequest(uri);
request.Headers.Add("myheader", "myheader_value");
return request;
}
Make sure you remove the DebuggerStepThroughAttribute
attribute if you want to step into it.
DebuggerStepThroughAttribute
如果您想进入该属性,请确保删除该属性。
回答by Valdemar Carneiro
I find this code and is resolve my problem.
我找到了这个代码并解决了我的问题。
http://arcware.net/setting-http-header-authorization-for-web-services/
http://arcware.net/setting-http-header-authorization-for-web-services/
protected override WebRequest GetWebRequest(Uri uri)
{
// Assuming authValue is set from somewhere, such as the config file
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
request.Headers.Add("Authorization", string.Format("Basic {0}", authValue));
return request;
}
回答by Attiq Rehman
Here is what worked for me:
这是对我有用的:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request;
request = (HttpWebRequest)base.GetWebRequest(uri);
NetworkCredential networkCredentials =
Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding().GetBytes(
networkCredentials.UserName + ":" +
networkCredentials.Password);
request.Headers["Authorization"] =
"Basic " + Convert.ToBase64String(credentialBuffer);
request.Headers["Cookie"] = "BCSI-CS-2rtyueru7546356=1";
request.Headers["Cookie2"] = "$Version=1";
}
else
{
throw new ApplicationException("No network credentials");
}
return request;
}
Don't forget to set this property:
不要忘记设置这个属性:
service.Credentials = new NetworkCredential("username", "password");
Cookie and Cookie2 are set in header because java service was not accepting the request and I was getting Unauthorized error.
Cookie 和 Cookie2 设置在标头中,因为 Java 服务不接受请求并且我收到未经授权的错误。
回答by Saeb Amini
Instead of modding the auto-generated code or wrapping every call in duplicate code, you can inject your custom HTTP headers by adding a custom message inspector, it's easier than it sounds:
您可以通过添加自定义消息检查器来注入自定义 HTTP 标头,而不是修改自动生成的代码或将每个调用包装在重复的代码中,这比听起来容易:
public class CustomMessageInspector : IClientMessageInspector
{
readonly string _authToken;
public CustomMessageInspector(string authToken)
{
_authToken = authToken;
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var reqMsgProperty = new HttpRequestMessageProperty();
reqMsgProperty.Headers.Add("Auth-Token", _authToken);
request.Properties[HttpRequestMessageProperty.Name] = reqMsgProperty;
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{ }
}
public class CustomAuthenticationBehaviour : IEndpointBehavior
{
readonly string _authToken;
public CustomAuthenticationBehaviour (string authToken)
{
_authToken = authToken;
}
public void Validate(ServiceEndpoint endpoint)
{ }
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{ }
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{ }
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new CustomMessageInspector(_authToken));
}
}
And when instantiating your client class you can simply add it as a behavior:
在实例化您的客户端类时,您可以简单地将其添加为行为:
this.Endpoint.EndpointBehaviors.Add(new CustomAuthenticationBehaviour("Auth Token"));
This will make every outgoing service call to have your custom HTTP header.
这将使每个传出服务调用都具有您的自定义 HTTP 标头。
回答by Tiago Martins
user334291's answer was a life saver for me. Just want to add how you can add what the OP originally intended to do (what I ended up using):
user334291 的回答对我来说是救命稻草。只想添加如何添加 OP 最初打算执行的操作(我最终使用的):
Overriding the GetWebRequest function on the generated webservice code:
在生成的网络服务代码上覆盖 GetWebRequest 函数:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.WebRequest request = base.GetWebRequest(uri);
string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(this.Credentials.GetCredential(uri, "Basic").UserName + ":" + this.Credentials.GetCredential(uri, "Basic").Password));
request.Headers.Add("Authorization", auth);
return request;
}
and setting the credentials before calling the webservice:
并在调用 Web 服务之前设置凭据:
client.Credentials = new NetworkCredential(user, password);