2010-06-09 3 views
0

Je vais d'abord montrer le code qui fonctionne dans un environnement non-ssl (http). Ce code utilise un gestionnaire d'erreur json personnalisé, et toutes les erreurs lancées, sont passées au javascript du client (ajax).Windows Service hébergement objets WCF sur SSL (https) - Gestion des erreurs JSON personnalisé ne fonctionne pas

 // 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(); 

Je vais aussi vous montrer ce qui ressemble la classe FaultingWebHttpBehavior comme:

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; 
} 

La méthode AddServerErrorHandlers() est appelée automatiquement, une fois webServiceHost.Open() est appelée. Cela configure le gestionnaire d'erreur json personnalisé, et la vie est bonne :-)

Le problème vient, quand nous passons à l'environnement SSL (https). Je vais maintenant vous montrer le code de création point final pour 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); 

Maintenant, avec ce code de point de terminaison SSL, le service démarre correctement, et les objets hébergé WCF peuvent être communiqués avec très bien via javascript client. Toutefois, le gestionnaire d'erreurs personnalisées ne fonctionne pas. La raison en est que la méthode AddServerErrorHandlers() n'est jamais appelée lorsque webServiceHost.Open() est exécuté. Donc, quelqu'un peut-il me dire quel est le problème avec cette image? Et pourquoi AddServerErrorHandlers() n'est pas appelé automatiquement, comme c'est le cas lorsque j'utilise des points de terminaison non-ssl?

Merci!

Répondre

0

Je vous renvoie à MSDN docs

Si la valeur du transport est spécifiée par la WebHttpBinding (WebHttpSecurityMode), puis les paramètres fournis par la propriété de transport en vigueur pour le point de terminaison de service. ne peut être réglé la valeur de WebHttpSecurityMode dans le constructeur de WebHttpBinding que il prend comme un paramètre explicite et sa valeur ne peut être réglée à nouveau après l'instance de liaison est créé.

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

Vous avez donc besoin de passer cette valeur

binding.Security.Mode = WebHttpSecurityMode.Transport; 

dans votre .ctor() comme

WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.Transport); 

Je ne l'ai jamais utilisé auparavant comme je toujours déclarer mes liaisons dans le fichier web.config mais selon MSDN, voici ce que vous devriez faire.

+0

Eh bien, je dirais que c'est une bonne découverte de votre part. Les mauvaises nouvelles sont, ça ne marche toujours pas. Le service se comporte exactement de la même manière. Il démarre correctement, mais le AddServerErrorHandlers() n'est jamais appelé, donc les erreurs ne sont jamais traitées ... – bpatrick100

+0

Du debug usign Casini ou IIS? Rappelez-vous que Casini n'est pas identique à IIS (ex: il n'est pas multi-threadé) –

+0

Aucun des deux n'est dans l'image ici. La méthode AddServerErrorHandlers() dans FaultingWebHttpBehavior() doit être appelée automatiquement lors du démarrage du service lors de l'appel de webServiceHost.Open() (C'est exactement ce qui se passe avec les points de terminaison non-SSL (http), et cela fonctionne parfaitement.Donc, pour tester, je démarre simplement le service avec un point d'arrêt dans AddServerErrorHandlers() - il est frappé avec les points de terminaison http, et ne pas frapper avec les points de terminaison https ... – bpatrick100

Questions connexes