El uso de IErrorHandler y TCP Message Security provoca un tiempo de espera

Tengo un servicio WCF con un IServiceBehavior personalizado adjunto que se utiliza para devolver una falla específica en el lado del cliente. Cuando habilito este código con TCP Message Security, recibo un tiempo de espera del servicio.

A continuación, puede ver el código completo del cliente y del servidor para reproducir el error.

Código del servidor:

usando el sistema; utilizando System.Collections.Generic; utilizando System.Linq; usando System.Text; utilizando System.ServiceModel; using System.ServiceModel.Description; utilizando System.ServiceModel.Dispatcher; utilizando System.ServiceModel.Channels; espacio de nombres TestWCFServer {class Program {static void Main (string [] args) {Console.WriteLine ("SERVIDOR"); Enlace NetTcpBinding = nuevo NetTcpBinding (); binding.Security.Mode = SecurityMode.Message; // ¡Si eliminas esta línea, el código funciona! Dirección de Uri = nueva Uri ("net.tcp: // localhost: 8184 /"); // Crea el ServiceHost. usando (ServiceHost host = new ServiceHost (typeof (HelloWorldService))) {host.AddServiceEndpoint (typeof (IHelloWorldService), enlace, dirección); host.Description.Behaviors.Add (nuevo MyErrorhandlerBehavior ()); host.Open (); Console.WriteLine ("El servicio está listo en {0}", dirección); Console.WriteLine ("Presione para detener el servicio."); Console.ReadLine (); // Cierre el ServiceHost. host.Close (); }}} [ServiceContract] interfaz pública IHelloWorldService {[OperationContract] cadena SayHello (nombre de cadena); } clase pública HelloWorldService: IHelloWorldService {cadena pública SayHello (nombre de la cadena) {si (nombre == null) lanza una nueva ArgumentNullException ("nombre"); return string.Format ("Hola, {0}", nombre); }} class MyErrorhandlerBehavior: IServiceBehavior, IErrorHandler {#region IServiceBahvior public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, BindingParameterCollection ServiceBahvior bindingParavior, Aplicar) { chanDisp en serviceHostBase.ChannelDispatchers) {chanDisp.ErrorHandlers.Add (this); }} public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {} #endregion #region IErrorHandler Miembros public bool HandleError (Error de excepción) {return true; } public void ProvideFault (Error de excepción, MessageVersion ver, ref Message msg) {FaultException fe = new FaultException (error.Message); MessageFault error = fe.CreateMessageFault (); msg = Message.CreateMessage (ver, error, "net.tcp: // localhost: 8184 / error"); } #endregion}}

Codigo del cliente:

usando el sistema; utilizando System.Collections.Generic; utilizando System.Linq; usando System.Text; utilizando System.ServiceModel; utilizando System.ServiceModel.Channels; using System.ServiceModel.Description; utilizando System.ServiceModel.Dispatcher; espacio de nombres TestWCFClient {class Program {static void Main (string [] args) {Console.WriteLine ("CLIENTE"); intente {NetTcpBinding binding = new NetTcpBinding (); binding.Security.Mode = SecurityMode.Message; // ¡Si eliminas esta línea, el código funciona! Dirección de Uri = nueva Uri ("net.tcp: // localhost: 8184 /"); EndpointAddress endpoint = new EndpointAddress (dirección); Cliente HelloWorldServiceClient = nuevo HelloWorldServiceClient (enlace, punto final); Console.WriteLine ("Llamando al cliente con un parámetro válido ..."); Console.WriteLine (client.SayHello ("Davide")); Console.WriteLine ("Aceptar"); Console.WriteLine ("Llamando al cliente con un parámetro no válido ..."); Console.WriteLine (cliente.SayHello (nulo)); // Esta llamada provoca el tiempo de espera cuando la seguridad se establece en Message Console.WriteLine ("OK"); } catch (Exception ex) {Console.WriteLine (ex.Message); } Console.WriteLine ("Presione enter para salir"); Console.ReadLine (); }} [ServiceContract] interfaz pública IHelloWorldService {[OperationContract] cadena SayHello (nombre de cadena); } clase HelloWorldServiceClient: System.ServiceModel.ClientBase, IHelloWorldService {Public HelloWorldServiceClient (System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress address): base (binding, address) {} public string SayHello (string name) {return base .Channel.SayHello (nombre); }}}

Si elimino el binding.Security.Mode = SecurityMode.Message; línea en el cliente y en el servidor la excepción se traduce correctamente y el cliente puede verla sin problemas.

En el registro de WCF veo estos mensajes:
No se especificaron partes del mensaje de firma para los mensajes con la acción 'net.tcp: // localhost: 8184 / failure'.
El protocolo de seguridad no puede proteger el mensaje saliente.

¿Alguna idea de cómo solucionar este problema? Parece que debo firmar / cifrar el mensaje de error, pero no sé cómo ...
Si utilizo la seguridad de transporte, el código funciona como se esperaba.

gracias!

preguntado el 06 de septiembre de 10 a las 07:09

2 Respuestas

Puede que sea un poco tarde para responder, pero tuve el mismo problema y lo descubrí:

Necesitas definir FaultContract en sus métodos de interfaz junto con OperationContract. Echar un vistazo aquí.

Además, su objeto de contrato de falla debe tener el mismo espacio de nombres que el espacio de nombres de Acción.

Taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaañada- pero finalmente me di cuenta y funciona ahora.

respondido 09 mar '11, 23:03

Gracias, tienes razón. En mi caso, el problema fue el espacio de nombres. También puedo ponerlo en nulo para no repetir el espacio de nombres cada vez. Mira mi respuesta ... - Davide Icardi

En mi caso, el problema estaba en el espacio de nombres. He reemplazado el método ProvideFault con esto:

public void ProvideFault(Exception error,MessageVersion ver, ref Message     
{
        FaultException fe = new FaultException(error.Message);
        MessageFault fault = fe.CreateMessageFault();
        msg = Message.CreateMessage(ver, fault, null);
}

Nota la null parámetro.

Tenga en cuenta también que con el espacio de nombres incorrecto, la excepción no se serializa correctamente.

Respondido el 09 de diciembre de 10 a las 10:12

Gracias. ¡Ojalá otros no tengan que pasar por el dolor que nosotros pasamos! - Alióstad

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.