2010-10-01 12 views
8

Tengo un servicio web asp.net clásico (asmx) y un método web en él. Necesito arrojar una excepción personalizada para algún caso en mi método web, y necesito detectar esa excepción personalizada específica donde llamo al método de servicio web.Captura de una excepción personalizada lanzada por un WebMethod en ASP.NET WebService

[WebService(Namespace = "http://tempuri.org/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
public class WebService : System.Web.Services.WebService 
{ 
    [WebMethod] 
    public HelloWorldOutput HelloWorld(HelloWorldInput input) 
    { 
     try 
     { 
      // My Code 
      return new HelloWorldOutput(); 
     } 
     catch (Exception ex) 
     { 
      throw new HelloWorldException("Hello World Exception", ex); 
     } 
    } 
} 

clases de entrada, de salida y de excepción como una muestra:

public class HelloWorldInput { } 
public class HelloWorldOutput { }  

[Serializable] 
public class HelloWorldException : Exception 
{ 
    public HelloWorldException() { } 
    public HelloWorldException(string message) : base(message) { } 
    public HelloWorldException(string message, Exception inner) 
     : base(message, inner) { } 
    protected HelloWorldException(
     System.Runtime.Serialization.SerializationInfo info, 
     System.Runtime.Serialization.StreamingContext context) 
     : base(info, context) { } 
} 

En el lado del cliente, que necesitan:

public static void Main() 
{ 
    WebService service = new WebService(); 
    try 
    { 
     service.HelloWorld(new HelloWorldInput()); 
    } 
    catch (HelloWorldException ex) 
    { 
     // Do sth with HelloWorldException 
    } 
    catch (Exception ex) 
    { 
     // Do sth with Exception 
    } 
} 

Sin embargo, no puedo hacer eso porque cuando agrego el referencia del servicio web en el cliente, tengo clase de servicio, clases de entrada y salida, pero no tengo clase de excepción personalizada.

También otro problema es que, también tengo problemas con la serialización de la clase de excepción (a causa de la propiedad Exception.Data implementa la interfaz IDictionary)

¿Hay una manera de hacer esto en mi camino, o estoy en un completamente manera incorrecta, o hay algo que extraño sobre los fundamentos de los servicios web?

Gracias.

Respuesta

11

Servicio Web ASP.NET puede lanzar cualquier tipo de excepción: SoapException , HelloWorldException o lo que sea. Sin embargo, la excepción se serializa en un elemento SOAP Fault e, independientemente del tipo de excepción que se arroje en el servicio, la excepción se convierte en SoapException mientras se deserializa. Por lo tanto, no es posible capturar la HelloWorldException con mi bloque catch en mi pregunta, incluso si despliegue HelloWorldException para el cliente.

Para un cliente ASP.NET, la única forma es detectar la excepción como SoapException y manejarla mediante su propiedad Actor o SoapFaultSubCode.

he resuelto mi problema básicamente de la siguiente manera:

servicio Web:

[WebService(Namespace = "http://tempuri.org/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
public class WebService : System.Web.Services.WebService 
{ 
    [WebMethod] 
    public HelloWorldOutput HelloWorld(HelloWorldInput input) 
    { 
     try 
     { 
      // My Code 
      return new HelloWorldOutput(); 
     } 
     catch (Exception ex) 
     { 
      throw new SoapException("Hello World Exception", 
       SoapException.ServerFaultCode, "HelloWorld", ex); 
     } 
    } 
} 

Cliente:

public static void Main() 
{ 
    WebService service = new WebService(); 
    try 
    { 
     service.HelloWorld(new HelloWorldInput()); 
    } 
    catch (SoapException ex) 
    { 
     if(ex.Actor == "HelloWorld") 
      // Do sth with HelloWorldException 
    } 
    catch (Exception ex) 
    { 
     // Do sth with Exception 
    } 
} 

Junto con el documento que Bryce Fischer escribió en su respuesta; estos documentos msdn también tienen información útil sobre cómo lanzar y manejar excepciones de servicios web.

How to: Throw Exceptions from a Web Service Created Using ASP.NET

How to: Handle Exceptions Thrown by a Web Service Method

+0

Debe establecer customErrors mode = 'RemoteOnly' o 'On' en su web.config – eddy

4

This pueden ser de ayuda. Parece que obtendrá una SoapException, pero puede inspeccionar los detalles para determinar si es su clase o no.

Nota al margen, para tener acceso a "HelloWorldException", se puede tirar de él hacia fuera en un conjunto separado e implementarla en el cliente ...

+0

El enlace que ha compartido era Bryce muy útil. Gracias. Eso me ayuda a darme cuenta del comportamiento de las excepciones del servicio web. Sin embargo, la implementación de la clase de excepción para el cliente será una elección tardía para mí. Pensaré sobre el tema por un tiempo. Muchas gracias. –

Cuestiones relacionadas