Мне нужно изменить привязку для веб-сервисов wcf с tcpbinding на webhttpbinding с базовой аутентификацией c и ssl.
Веб-сервисы размещаются самостоятельно в консольном приложении и в сервисе windows для рабочей версии. Некоторые локальные службы имеют привязку именованного канала, просто если служба вызывает другую службу.
Все работает отлично, но не глобальный менеджер ошибок (класс, реализующий интерфейс IErrorHandler)
Некоторые из DAL или бизнес-методы выдают исключение с пользовательским сообщением, и это сообщение было правильно передано клиенту (некоторое время модульное тестирование). Но поскольку я изменяю привязку, исключения, обнаруженные в модульном тесте, всегда являются ошибкой 500, внутренняя ошибка сервера и пользовательские сообщения не являются объектом исключения.
Код сервера:
// 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();
Бизнес-метод, который исключение выброса:
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);
}
}
Ошибка глобального менеджера:
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);
}
}
Модульный тест:
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);
}
}
Все модульные тесты, которые перехватили исключение, не были выполнены, поскольку я изменил привязку.
Спасибо за помощь.