Служба Windows, размещающая объекты WCF через SSL (https) - пользовательская обработка ошибок JSON не работает - PullRequest
0 голосов
/ 09 июня 2010

Сначала я покажу код, который работает в среде, отличной от 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?

Спасибо!

1 Ответ

0 голосов
/ 09 июня 2010

Я отошлю вас к документам MSDN

Если значение транспорта указано в привязке WebHttpBinding (WebHttpSecurityMode), то параметры, предоставленные свойством Transport, вступают в силу для конечной точки службы.Значение WebHttpSecurityMode может быть установлено только в конструкторе WebHttpBinding, который принимает его в качестве явного параметра, и его значение не может быть снова установлено после создания экземпляра привязки.

см .: http://msdn.microsoft.com/en-us/library/bb348328.aspx

Так что вам нужно передать это значение

binding.Security.Mode = WebHttpSecurityMode.Transport;

в ваш .ctor () вот так

WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.Transport);

Я никогда не использовал это раньше, так как всегда объявляю свои привязки в сетиФайл .config, но, согласно MSDN, это то, что вам следует делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...