I have a problem that I'm not quite sure how it started. I am pretty sure that it worked fine, but I donβt remember to make any changes.
First, please do not focus too much on tuning unless this directly affects why it is not working. I'm not looking for criticism as much as I do, which makes it not work.
I am showing an API that uses HTTP header authentication. I use this API in my solution. To avoid the template code, I created a ClientFactory that I want to initialize with services using CustomClientMessageInspector and CustomCredentialBehavior , which is responsible for adding headers to the message.
The idea is that when I need to use the service, the code will look something like this:
IClientCredentials credentials = ClientCredentials.FromToken(); var service = ClientFactory.CreateClientInstance<API.Clients.ClientServiceClient>(credentials);
The Factory client is as follows (please do not judge too much about it).
public class ClientFactory { public static T CreateClientInstance<T>(IClientCredentials clientCredentials) { T t = Activator.CreateInstance<T>(); var factory = t.GetType().GetProperty("ChannelFactory"); using (var scope = new OperationContextScope((IContextChannel) t.GetType().GetProperty("InnerChannel").GetValue(t,null))) { var endpointBehavior = new CustomCredentialBehavior(clientCredentials); if (((ChannelFactory) factory.GetValue((t),null)).Endpoint.Behaviors.Any(p => p.GetType() == typeof(CustomCredentialBehavior))) { var behavior = ((ChannelFactory) factory.GetValue((t),null)).Endpoint.Behaviors.FirstOrDefault( p => p.GetType() == typeof (CustomCredentialBehavior)); ((ChannelFactory) factory.GetValue((t),null)).Endpoint.Behaviors.Remove(behavior); } ((ChannelFactory)factory.GetValue((t),null)).Endpoint.Behaviors.Add(endpointBehavior); return t; } } }
CustomEndpointBehavior:
public class CustomCredentialBehavior:IEndpointBehavior { private IClientCredentials _clientCredentials { get; set; } public CustomCredentialBehavior(IClientCredentials clientCredentials) { _clientCredentials = clientCredentials; } 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.MessageInspectors.Add(new ClientCredentialMessageInspector(_clientCredentials)); } }
ClientMessageInspector:
public class ClientCredentialMessageInspector:IClientMessageInspector { private IClientCredentials _clientCredentials; public ClientCredentialMessageInspector(IClientCredentials clientCredentials) { _clientCredentials = clientCredentials; } public object BeforeSendRequest(ref Message request, IClientChannel channel) { var buffer = request.CreateBufferedCopy(Int32.MaxValue); request = buffer.CreateMessage(); HttpRequestMessageProperty messageProperty = (HttpRequestMessageProperty) request.Properties["httpRequest"]; messageProperty.Headers.Add("AccessKey", _clientCredentials.AccessKey.ToString()); messageProperty.Headers.Add("ClientKey", _clientCredentials.ClientKey.ToString()); messageProperty.Headers.Add("AuthorizationKey", _clientCredentials.AuthorizationKey); return null; } public void AfterReceiveReply(ref Message reply, object correlationState) { } }
The problem I'm running into is that even if I see a service returned from ClientFactory with the correct endpoint behavior, ApplyClientBehavior () is never called. For some reason, it does not seem to use the WCF utility as it was originally.
How do I get ClientFactory to instantiate to add EndpointBehavior?
EDIT . To show what I'm looking at, here is a screenshot of the clock window right before calling the service. It shows that my CustomCredentialBehavior is initialized with all the correct values.

EDIT I took the advice of Carlos (in the comments) and simplified the call and used the next call instead. I am glad that it works, however, I would like to find out where the problem is in my source code, so I do not need to call the boilerplate code every time I need to use the service link.
The following code works:
API.Clients.Client client = new API.Clients.Client(); client.Active = true; client.Enabled = true; client.Name = model.ClientName; API.Clients.ClientServiceClient service = new ClientServiceClient(); service.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentialBehavior(ClientCredentials.FromToken())); var response = service.CreateClient(new CreateClientRequest() { Client = client });
Any idea why the source code is not working and it does?