Usando objeto personalizado que contiene FaultContract causas System.Exception 'Agregar referencia de servicio' a fallar

StackOverflow https://stackoverflow.com/questions/4656257

Pregunta

Yo sólo notó algo en particular. Tengo un servicio de inventario interno que se publica a través basicHttpBinding, y una customBinding (http + binario) para los cuales está habilitado metadatos. También he incluido un punto final para http Mex. Utilizamos Visual Studio 2008 y VB.NET

Hace poco nos dimos cuenta de que no hemos podido añadir con éxito una referencia de servicio a este servicio en nuestros otros proyectos. Todo lo que generaría fue la primera excepción personalizada incluimos a través de un FaultContract (en realidad, sólo había 1 tipo). si me gustaría añadir una simple referencia Web que funcionaría correctamente también. Además, el WcfClient.exe no tuvo problemas, ya sea en la carga de los servicios. Sólo VS.NET referencia de servicio complemento no funcionaría.

En el servicio de esta excepción hereda de excepción y está marcado como serializable. Eso es todo lo que tienes que hacer, ¿no?

De todos modos, esto me tenía desconcertado. Si quito el FaultContract para esta excepción personalizada todo funciona bien. Puedo añadir una referencia de servicio, no hay problema. Pero hay una manera que todavía puedo tener mis excepciones personalizadas? ¿Es un problema conocido?

¿Fue útil?

Solución

me encontré con esto mismo hoy. La solución fue usar un objeto no heredando de excepción en el FaultContract. Si nos fijamos en la documentación de MSDN para FaultException y FaultContract verá que los ejemplos oficiales utilizan las clases de civil ( con atributos de Datacontact) en lugar de las clases que se extienden Excepción para FaultException.Detail. No estoy seguro de por qué excepción hace la opción Agregar referencia de servicio a fallar, pero sospecho que tiene que ver con la serialización o recuperar la información de tipo de excepciones personalizadas. He incluido antes y después de implementaciones de ejemplo para demostrar el enfoque de trabajo.

Antes (no funcionó):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyException))]
    MyResults MyServiceOperation(string myParameter);
}

[Serializable]
public class MyException : Exception
{
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyException>(new MyException { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

Después (trabajado):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyFault))]
    MyResults MyServiceOperation(string myParameter);
}

[DataContract]
public class MyFault
{
    [DataMember]
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyFault>(new MyFault { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

Fuente: Max Strini para el uso de su código y ayuda para encontrar la solución a este problema <. / p>

Otros consejos

He encontrado el siguiente artículo sobre cómo crear un contrato de errores con objetado heredada de System.Exception: http://blog.clauskonrad.net/2008/06/wcf-and-custom-exceptions.html

Sin embargo, no funcionó para mí. Sospecho que la razón no funcionó para mí es que estoy usando un BasicHttp vinculante y no un NET-NET vinculante.

También hemos topado con este problema. Terminé usando el svcutil.exe para generar el proxy que no parece sufrir el mismo problema.

I tenía el mismo problema y lo resolvió mediante la generación de la proxy utilizando Svcutil.exe. Tenía la configuración personalizada falla exactamente la forma en MSDN recomienda pero "add referencia de servicio" no estaba incluido el contrato de fallo en el proxy. Luego utiliza el Svcutil y funcionó como magia:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top