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

时间:2009-05-22 13:16:33

标签: c# web-services wsdl axis

我正在尝试在c#中编写Web服务客户端,其中webservice是Java Axis 1.4。 Axis服务需要HTTP标头中的授权:基本Base64EncodedToken 标头值。 我无法找到一种方法来在visual studio.net中以不同的方式设置此标头,就像正常的WSDL生成引用一样,也不能使用WSE3.0

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

有没有办法做到这一点?

7 个答案:

答案 0 :(得分:46)

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

如果要插入DebuggerStepThroughAttribute属性,请务必删除它。

答案 1 :(得分: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);
   }

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

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

答案 2 :(得分:7)

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

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("Authorization", token);

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

答案 3 :(得分:6)

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

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

this.Endpoint.EndpointBehaviors.Add(new CustomAuthenticationBehaviour("Auth Token"));

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

答案 4 :(得分: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;
}

答案 5 :(得分:1)

user334291的答案对我来说是一个救生员。只想添加如何添加OP最初打算做的事情(我最终使用的内容):

在生成的Web服务代码上覆盖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;
}

并在调用webservice之前设置凭据:

  client.Credentials = new NetworkCredential(user, password);       

答案 6 :(得分:0)

这对我有用:

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;
}

不要忘记设置此属性:

service.Credentials = new NetworkCredential("username", "password");  

Cookie和Cookie2在标头中设置,因为java服务不接受请求而我收到了未经授权的错误。