如何为使用Axis 1.4 Web服务的C#Web服务客户端添加自定义Http Header

Umu*_*tKa 48 c# axis wsdl web-services

我正在尝试在c#中编写一个Web服务客户端,其Web服务是Java Axis 1.4.Axis服务需要HTTP标头中的Authorization:Basic Base64EncodedToken标头值.我找不到一种方法来在visual studio.net中以不同的方式设置这个头文件,就像普通的WSDL生成引用一样,也不是WSE3.0

我不能使用WCF,因为项目是使用.net 2.0开发的.

有没有办法做到这一点?

小智 48

原作者似乎找到了他们的解决方案,但对于其他任何想要添加实际自定义标头的人来说,如果您有权访问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;
}
Run Code Online (Sandbox Code Playgroud)

DebuggerStepThroughAttribute如果要进入该属性,请确保删除该属性.

  • 我把它与"reference.cs"文件一起放在了一个部分类中,这样如果它被重新编写它就不会丢失. (3认同)
  • 嘿,这似乎正是我所需要的.但是我应该把这个功能放在哪里? (2认同)

小智 25

我们在这里谈论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);
   }
Run Code Online (Sandbox Code Playgroud)

这是通过.NET运行对IBM ESB的SOAP调用,通过http或https进行基本身份验证.

我希望这可以帮助别人,因为我在网上找到解决方案时遇到了大量问题.

  • 这实际上是我的问题.不知何故,当您在代理中设置凭据时,它不起作用.谢谢! (2认同)

Sae*_*ini 10

您可以通过添加自定义消息检查器来注入自定义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));
    }
}
Run Code Online (Sandbox Code Playgroud)

在实例化您的客户端类时,您只需将其添加为行为:

this.Endpoint.EndpointBehaviors.Add(new CustomAuthenticationBehaviour("Auth Token"));
Run Code Online (Sandbox Code Playgroud)

这将使每个传出服务调用都具有您的自定义HTTP标头.

  • Saeb Amini,谢谢.这是我正在寻找的解决方案,使用已经改为双因素身份验证的第三方Web服务来解决我的问题.他们的API由XSD和WSDL提供给我们,我们通过svcutil程序生成客户端代码.使用上面的代码允许我添加行为以使用令牌注入HTTP标头以执行双因素身份验证.再次感谢! (2认同)

Joh*_*ter 7

如果要发送自定义HTTP标头(而不是SOAP标头),则需要使用代码如下的HttpWebRequest类:

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("Authorization", token);
Run Code Online (Sandbox Code Playgroud)

您无法使用visual studio生成的代理添加HTTP标头,这可能是一个真正的痛苦.


小智 5

我找到这个代码并解决了我的问题.

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿,这似乎正是我所需要的.但是我应该把这个功能放在哪里? (2认同)