2008-08-28 18 views
15

tengo una simple operación de servicio web como éste:¿Cómo se extrae la excepción interna de una excepción soap en ASP.NET?

[WebMethod] 
    public string HelloWorld() 
    { 
     throw new Exception("HelloWorldException"); 
     return "Hello World"; 
    } 

Y luego tengo una aplicación cliente que consume el servicio web y luego llama a la operación. Obviamente va a lanzar una excepción :-)

try 
    { 
     hwservicens.Service1 service1 = new hwservicens.Service1(); 
     service1.HelloWorld(); 
    } 
    catch(Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 

En mi bloque catch, lo que me gustaría hacer es extraer el mensaje de la excepción real para usarlo en mi código. La excepción capturada es un SoapException, lo cual está bien, pero es Message propiedad es así ...

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception: HelloWorldException 
    at WebService1.Service1.HelloWorld() in C:\svnroot\Vordur\WebService1\Service1.asmx.cs:line 27 
    --- End of inner exception stack trace --- 

... y el InnerException es null.

Lo que me gustaría hacer es extraer la propiedad Message del InnerException (el HelloWorldException texto en mi muestra), ¿alguien puede ayudar con eso? Si puede evitarlo, no sugiera analizar la propiedad Message del SoapException.

Respuesta

6

Lamentablemente, no creo que esto sea posible.

La excepción que está generando en su código de servicio web está siendo codificada en una falla de jabón, que luego se pasa como una cadena de vuelta a su código de cliente.

Lo que está viendo en el mensaje SoapException es simplemente el texto de la falla de Soap, que no se está convirtiendo nuevamente a una excepción, sino simplemente almacenado como texto.

Si desea devolver información útil en condiciones de error, le recomiendo que devuelva una clase personalizada de su servicio web que puede tener una propiedad "Error" que contenga su información.

[WebMethod] 
public ResponseClass HelloWorld() 
{ 
    ResponseClass c = new ResponseClass(); 
    try 
    { 
    throw new Exception("Exception Text"); 
    // The following would be returned on a success 
    c.WasError = false; 
    c.ReturnValue = "Hello World"; 
    } 
    catch(Exception e) 
    { 
    c.WasError = true; 
    c.ErrorMessage = e.Message; 
    return c; 
    } 
} 
+1

¿Por qué crear una clase personalizada si podría lograrlo sin uno? Por favor revisa mi respuesta en esta publicación. – BornToCode

1

me encontré con algo similar hace un poco y blogged about it. No estoy seguro si es exactamente aplicable, pero podría ser. El código es lo suficientemente simple una vez que te das cuenta de que tienes que pasar por un objeto MessageFault. En mi caso, sabía que el detalle contenía un GUID que podría usar para volver a consultar el servicio SOAP para más detalles. El código es el siguiente:

catch (FaultException soapEx) 
{ 
    MessageFault mf = soapEx.CreateMessageFault(); 
    if (mf.HasDetail) 
    { 
     XmlDictionaryReader reader = mf.GetReaderAtDetailContents(); 
     Guid g = reader.ReadContentAsGuid(); 
    } 
} 
4

Se ES posible!

Servicio Ejemplo de operación:

try 
{ 
    // do something good for humanity 
} 
catch (Exception e) 
{ 
    throw new SoapException(e.InnerException.Message, 
          SoapException.ServerFaultCode); 
} 

Cliente consumo del servicio:

try 
{ 
    // save humanity 
} 
catch (Exception e) 
{ 
    Console.WriteLine(e.Message);  
} 

Sólo una cosa - que necesita para establecer el modo customErrors = 'RemoteOnly' o 'On' en su web. config (del proyecto de servicio).

créditos sobre el descubrimiento customErrors - http://forums.asp.net/t/236665.aspx/1

+0

Creo que te refieres a 'lanzar una nueva SoapException (e.Message, ...' en lugar del mensaje InnerException de la excepción atrapada. – Timothy

Cuestiones relacionadas