How to add custom Http Header for C# Web Service Client consuming Axis 1.4 Web service

188,199

Solution 1

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:

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.

Solution 2

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.

  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.

I hope this helps someone out because I had massive issues finding a solution online.

Solution 3

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:

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.

Solution 4

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:

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.

Solution 5

I find this code and is resolve my problem.

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;
}
Share:
188,199
UmutKa
Author by

UmutKa

Updated on July 09, 2022

Comments

  • UmutKa
    UmutKa almost 2 years

    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 Base64EncodedToken header 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

    I can't use WCF as the project is developed using .net 2.0.

    Is there any way to do this ?

  • chaostheory
    chaostheory about 14 years
    "You cannot add HTTP headers using the visual studio generated proxy" Is this still the case?
  • g .
    g . over 13 years
    This was exactly what I needed. The Web Service was returning 500 instead of 401 for Unauthorized, so the credentials were never sent using the approach in the accepted answer. While I feel dirty modifying generated code, this allowed me to force send them with the first request. See west-wind.com/weblog/posts/243915.aspx.
  • Tawani
    Tawani over 12 years
    This was actually my problem. Somehow when you set the credentials in the proxy, it doesn't work. Thanks!
  • Roee Gavirel
    Roee Gavirel over 12 years
    Hey, that's seems like exactly what I need. but where should I put this function?
  • Roee Gavirel
    Roee Gavirel over 12 years
    Hey, that's seems like exactly what I need. but where should I put this function?
  • PositiveGuy
    PositiveGuy about 12 years
    but can't a header addition have multiple comma seperated values in the value portion for the header you're adding? That too is very important to know such as for OAuth Authorization params
  • Brady Moritz
    Brady Moritz almost 12 years
    I've put this in a partial class along with the "reference.cs" file, so that if it is regnerated it will not be lost.
  • Admin
    Admin almost 11 years
    I got rid of above overload and only this code did all magic: serviceClient.CookieContainer = new CookieContainer();
  • Joshy
    Joshy over 10 years
    I can add the headers like this but how do i get them back in the WCF Service?
  • Pertinent Info
    Pertinent Info almost 10 years
    I also don't know where to put it and I'm using .net 4.0. My service is generated differently than other examples I find
  • robnick
    robnick over 8 years
    I'm using WCF/Soap, so this worked really well for me. In my case I needed a custom header called "Auth-Token". So my (VB.NET) code was --> httpRequestProperty.Headers.Add("Auth-Token", "xxxxx")
  • merger
    merger almost 7 years
    This solved my problems also. I had the same problem as Tawani, when i set the credentials through the proxy i got back 401. But with your code everything works perfectly! Big thanks!
  • Mike Taverne
    Mike Taverne almost 7 years
    Excellent! Worked for me to set the Authorization header to include a Bearer token.
  • Mike Taverne
    Mike Taverne almost 7 years
    Hmmm... works great in the debugger, but after deploying to Azure, "The value of OperationContext.Current is not the OperationContext value installed by this OperationContextScope."
  • bolski
    bolski over 6 years
    Saeb Amini, thank you. This was the answer I was looking for to solve my issue using a 3rd party web service that had changed over to 2-factor authentication. Their API was provided to us by XSDs and WSDLs which we generated the client code via the svcutil program. Using the code above allowed me to add the behavior to inject the HTTP header with the token to do the 2-factor authentication. Thanks again!
  • Saeb Amini
    Saeb Amini almost 6 years
    @bolski great to know it's helped you! :)
  • rDroid
    rDroid almost 5 years
    I tried this out, works like a charm. Just had to create a partial class with same name as proxy and under same namespace as the webservice client proxy. and add this method inside that class.
  • Avid Programmer
    Avid Programmer over 4 years
    I have added my header in the above solution and its worked well. I faced the issue for adding security header in Soap Request. Thanks!
  • jcs
    jcs about 4 years
    Thanks! Taking yours as base, I've used a slightly different solution to add x-api-key to the HTTP headers of the request and it worked.
  • Barns
    Barns almost 3 years
    I ported my .Net Framwork code to .Net Core and was having issues with my CustomBehavior class. All I had to do was remove a few class inheritance that are apparently not needed in .Net Core. Thanks for adding ONLY the code needed!