I\'m working on a Windows Form application and there\'s a WCF service that needs to be called. I need to add a header (authorization - custom) to the request before it\'s se
The problem with your solution is that it would add an HTTP header. What you need is a SOAP header, however. That could be done like this...
using(new OperationContextScope(client.InnerChannel))
{
// Add a SOAP Header to an outgoing request
MessageHeader aMessageHeader = MessageHeader.CreateHeader("UserInfo", "http://tempuri.org", userInfo);
OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader);
}
If there's some problem with your BeforeSend method, this is how I implemented it when adding authentication to some webservice calls.
private const string Authorization = "Authorization";
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
object httpRequestMessageObject;
if (request.Properties.TryGetValue(
HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
var httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrWhiteSpace(httpRequestMessage.Headers[Authorization]))
{
httpRequestMessage.Headers[Authorization] = "Basic Y19udGk6Q29udGlfQjNTVA==";
}
}
else
{
var httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add(Authorization, "Basic Y19udGk6Q29udGlfQjNTVA==");
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
return null;
}
I know this is late but I ran across this post so decided to fill this in, in case I ever need to remember this again. This worked for me:
Create the Message Inspector:
Public Class AuthenticationHeader
Implements IClientMessageInspector
Private itsUser As String
Private itsPass As String
Public Sub New(ByVal user As String, ByVal pass As String)
itsUser = user
itsPass = pass
End Sub
Public Sub AfterReceiveReply(ByRef reply As Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply
Console.WriteLine("Received the following reply: '{0}'", reply.ToString())
End Sub
Public Function BeforeSendRequest(ByRef request As Message, channel As IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest
Dim hrmp As HttpRequestMessageProperty = request.Properties("httpRequest")
Dim encoded As String = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(itsUser + ":" + itsPass))
hrmp.Headers.Add("Authorization", "Basic " + encoded)
Return request
End Function
End Class
Write the Behavior:
Public Class AuthenticationHeaderBehavior
Implements IEndpointBehavior
Private ReadOnly itsUser As String
Private ReadOnly itsPass As String
Public Sub New(ByVal user As String, ByVal pass As String)
MyBase.New()
itsUser = user
itsPass = pass
End Sub
Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
End Sub
Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
clientRuntime.MessageInspectors.Add(New AuthenticationHeader(itsUser, itsPass))
End Sub
Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
End Sub
Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
End Sub
End Class
Add it to your endpoint:
Dim binding As New WebHttpBinding(WebHttpSecurityMode.Transport)
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
ChlFactory = New WebChannelFactory(Of IMyServiceContract)(binding, New Uri(url))
ChlFactory.Endpoint.Behaviors.Add(New WebHttpBehavior())
ChlFactory.Endpoint.Behaviors.Add(New AuthenticationHeaderBehavior(user, pass))
Channel = ChlFactory.CreateChannel()
The simplest way is to add it on the client side:
using (MyServ.ServiceClient proxy = new MyServ.ServiceClient())
{
using (new System.ServiceModel.OperationContextScope(proxy.InnerChannel))
{
MessageHeader head = MessageHeader.CreateHeader("Authorization", "http://yournamespace.com/v1", data);
OperationContext.Current.OutgoingMessageHeaders.Add(head);
}
}
and retrieve it on the server side:
string auth = OperationContext.Current.IncomingMessageHeaders.
GetHeader<string>("Authorization", "http://mynamespace.com/v1");
I also suggest that you check these articles:
Authorization Header is missing in Http request using WCF
WCF Service with wsHttpBinding - Manipulating HTTP request headers