Сначала я покажу код, который работает в среде, отличной от ssl (http). Этот код использует пользовательский обработчик ошибок json, и все выданные ошибки передаются клиентскому javascript (ajax).
// Create webservice endpoint
WebHttpBinding binding = new WebHttpBinding();
ServiceEndpoint serviceEndPoint = new ServiceEndpoint(ContractDescription.GetContract(Type.GetType(svcHost.serviceContract + ", " + svcHost.assemblyName)), binding, new EndpointAddress(svcHost.hostUrl));
// Add exception handler
serviceEndPoint.Behaviors.Add(new FaultingWebHttpBehavior());
// Create host and add webservice endpoint
WebServiceHost webServiceHost = new WebServiceHost(svcHost.obj, new Uri(svcHost.hostUrl));
webServiceHost.Description.Endpoints.Add(serviceEndPoint);
webServiceHost.Open();
Я также покажу вам, как выглядит класс FaultingWebHttpBehavior:
public class FaultingWebHttpBehavior : WebHttpBehavior
{
public FaultingWebHttpBehavior()
{
}
protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new ErrorHandler());
}
public class ErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
// Build an object to return a json serialized exception
GeneralFault generalFault = new GeneralFault();
generalFault.BaseType = "Exception";
generalFault.Type = error.GetType().ToString();
generalFault.Message = error.Message;
// Create the fault object to return to the client
fault = Message.CreateMessage(version, "", generalFault, new DataContractJsonSerializer(typeof(GeneralFault)));
WebBodyFormatMessageProperty wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);
}
}
}
[DataContract]
public class GeneralFault
{
[DataMember]
public string BaseType;
[DataMember]
public string Type;
[DataMember]
public string Message;
}
Метод AddServerErrorHandlers () вызывается автоматически после вызова webServiceHost.Open (). Это настраивает пользовательский обработчик ошибок JSON, и жизнь хороша: -)
Проблема возникает, когда мы переключаемся в среду SSL (https). Теперь я покажу вам код создания конечной точки для SSL:
// Create webservice endpoint
WebHttpBinding binding = new WebHttpBinding();
ServiceEndpoint serviceEndPoint = new ServiceEndpoint(ContractDescription.GetContract(Type.GetType(svcHost.serviceContract + ", " + svcHost.assemblyName)), binding, new EndpointAddress(svcHost.hostUrl));
// This exception handler code below (FaultingWebHttpBehavior) doesn't work with SSL communication for some reason, need to resarch...
// Add exception handler
serviceEndPoint.Behaviors.Add(new FaultingWebHttpBehavior());
//Add Https Endpoint
WebServiceHost webServiceHost = new WebServiceHost(svcHost.obj, new Uri(svcHost.hostUrl));
binding.Security.Mode = WebHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
webServiceHost.AddServiceEndpoint(svcHost.serviceContract, binding, string.Empty);
Теперь, с этим кодом конечной точки SSL, служба запускается правильно, и объекты, размещенные в wcf, могут быть легко переданы через клиентский javascript. Тем не менее, пользовательский обработчик ошибок не работает. Причина в том, что метод AddServerErrorHandlers () никогда не вызывается при запуске webServiceHost.Open ().
Так, может кто-нибудь сказать мне, что не так с этой картиной? И почему AddServerErrorHandlers () не вызывается автоматически, как это происходит, когда я использую конечные точки не-ssl?
Спасибо!