I have to change a binding for wcf webservices from tcpbinding to webhttpbinding with basic authentication and ssl.
Webservices are self hosted in a console application and in a windows service for production version. Some of local services are with named pipe binding, just if a service call another service.
All works perfectly but not the global error manager (a class that implement IErrorHandler interface)
Some of DAL or business methods throw an exception with a custom message and this message was correctly provide to client (unit test for a while). But since I change binding, exceptions caught in unit test are always a 500 error, internal server error and custom messages are not in exception object.
Server code :
// Création de l'URI
var baseAddress = new Uri($"https://localhost/blablabla/{typeof(TBusiness).Name}");
// Création du Host avec le type de la classe Business
var host = new ServiceHost(typeof(TBusiness), baseAddress);
// Liaison WebHttpBinding sécurité transport
var binding = new WebHttpBinding
{
MaxBufferSize = 2147483647,
MaxReceivedMessageSize = 2147483647,
Security = new WebHttpSecurity
{
Mode = WebHttpSecurityMode.Transport
},
};
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
// Permet de renvoyer du xml et du json
var webBehavior = new WebHttpBehavior
{
AutomaticFormatSelectionEnabled = true
};
var ep = host.AddServiceEndpoint(typeof(TContracts), binding, "");
ep.Behaviors.Add(webBehavior);
var sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.HttpHelpPageEnabled = false;
// Activation https
var smb = new ServiceMetadataBehavior
{
HttpGetEnabled = false,
HttpsGetEnabled = true,
};
host.Description.Behaviors.Add(smb);
// Ajout de l'authentification
var customAuthenticationBehavior = new ServiceCredentials();
customAuthenticationBehavior.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
customAuthenticationBehavior.UserNameAuthentication.CustomUserNamePasswordValidator = new SessionAuthentication();
host.Description.Behaviors.Add(customAuthenticationBehavior);
// Démarrage du host
host.Open();
Business method that throw exception :
public TOUser GetUserByLogin(string login)
{
using (var service = new ServiceProviderNamedPipe<IBFSessionManager, BSSessionManager>())
{
// Récupération de la DALUsers
var dal = service.Channel.GetDALUsers(OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name);
var user = dal.GetUserByLogin(login);
if (user == null) throw new FaultException(Errors.DALUsers_Err001);
return BMToolsEntitiesToTO.UserToTOUser(user);
}
}
Error global manager :
public class GlobalErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
// Empèche la propagation de l'erreur
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
var msg = error.Message;
// Création de l'exception de retour
var newEx = new FaultException(msg);
var msgFault = newEx.CreateMessageFault();
fault = Message.CreateMessage(version, msgFault, newEx.Action);
}
}
Unit test :
public void GetUserByLoginWithUnknownLoginTest()
{
TOUser user = null;
using (var service = new ServiceProviderHTTP<IBFUsers, BSUsers>(_user))
{
try
{
user = service.Channel.GetUserByLogin("1234");
}
catch (Exception e)
{
// e.message always provide "Internal server error instead of custom message (Errors.DALUsers_Err001)
Assert.AreEqual(Errors.DALUsers_Err001, e.Message);
}
Assert.IsNull(user);
}
}
All unit tests that catch exception failed since I change binding.
Thank you for your help.
I doubt whether your service is running correctly. Do you bind the certificate to the default port 443 due to transport layer security (using HTTPS)? Please use the below statement to bind a certificate to the 443 port.
please refer to this link.
https://learn.microsoft.com/en-us/windows/win32/http/add-sslcert
Here is a relevant discussion.
How to disable credentials input for HTTPS call to my WCF hosted in windows service
Besides, I didn’t see you apply the
GlobalErrorHandlerto the self-hosted service. This is usually implemented by service endpoint behavior.I wrote an example, wish it is useful to you.
Result.

Feel free to let me know if there is anything I can help with.