Cómo aceptar una SoapException en el lado del cliente

Obtuve el temido "cliente encontró el tipo de contenido de respuesta de" texto/html "pero esperaba el error" prueba/xml ", pero después de buscar en Google encontré esta publicación sobre cómo devolver una SoapException.

Así que seguí adelante y lo implementé, pero ahora sigo recibiendo el mismo error. ¿Hay cambios que deba hacer en el lado del cliente para poder aceptar SoapException (no lo creo, todo simplemente hereda de Exception, verdad?)

¿Por qué sigo recibiendo esa temida respuesta del lado del cliente?

    [WebMethod]
    [SoapHeader("authenticationHeader")]
    [WebServiceAuthentication(AuthenticationRequired = false)]
    public DataSet GetConversionErrors()
    {
        try
        {
            return Components.PWD.GetConversionErrors();
        }
        catch (Exception ex)
        {
            PublishingManager.Publish(ex, HttpContext.Current.User.Identity.Name);
            throw Components.SoapException.GenerateSoapException(ex, Context);
        }
    }

Editar: sé que la excepción en este bloque de captura es exactamente lo que necesito ver, pero todavía obtengo System.InvalidOperationException en el lado del cliente.

Edit2: me estoy conectando a los servicios web a través de una WebReference (llamando a un archivo * .asmx) si eso ayuda/importa.

Edit3: Esto es lo que se escribe en nuestro lado del servidor de registro de excepciones (en la llamada PublishingManager.Publish()). Mi pensamiento fue que esto debería ser lo que se devuelve al cliente...

Exception Details:
Exception Type: System.Exception
Message: Test the text/html text/xml message. 
Method: PWD.Components.PWD.GetConversionErrors 
Username: xxxxxx Created 5/22/2012 4:20:53 PM 
Application: xxxx Application Identity: NT AUTHORITY\IUSR 
Source: xxxx Severity 2 
Machine: xxxxxxxxx IP Address 127.0.0.1 
AppDomain /LM/W3SVC/1/ROOT-1-129821937733610609 
Stack Trace    at PWD.Components.PWD.GetConversionErrors() in C:\Vault\Development-New\Web\Main_Logging\PWD\Components\PWD.cs:line 73 
   at PWD.PWD.GetConversionErrors() in C:\Vault\Development-New\Web\Main_Logging\PWD\PWD.asmx.cs:line 44 
Additional Information:
  +System.Exception: 
    Message: Test the text/html text/xml message. 
    Data: System.Collections.ListDictionaryInternal 
    InnerException:  
    TargetSite: System.Data.DataSet GetConversionErrors() 
    StackTrace:    at PWD.Components.PWD.GetConversionErrors() in C:\Vault\Development-New\Web\Main_Logging\PWD\Components\PWD.cs:line 73 
   at PWD.PWD.GetConversionErrors() in C:\Vault\Development-New\Web\Main_Logging\PWD\PWD.asmx.cs:line 44 
    HelpLink:  
    Source: xxxx 
     UserName: xxxxxxx 
     TypeName: PublishingManager 
     MachineName: xxxxxxxxx 
     TimeStamp: 5/22/2012 4:20:54 PM 
     FullName: Services.Publishing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null 
     AppDomainName: /LM/W3SVC/1/ROOT-1-129821937733610609 
     ThreadIdentity:  
     WindowsIdentity: NT AUTHORITY\IUSR 
     Severity: 2 
     MachineIPAddress: 127.0.0.1 

Edit3: solo quiero lanzar este fragmento de código adicional para que la gente vea cómo estoy probando estas excepciones (y tal vez sea la forma incorrecta de probar...). En mi primer fragmento de código, tengo la llamada dentro del bloque de prueba para "devolver Componentes.PWD.GetConversionErrors();", aquí está ese método:

    public static DataSet GetConversionErrors()
    {
        DB db = new DB();

        try
        {
            //return db.ExecuteDataset(Configuration.GenericConfig.AppConnectionString, CommandType.Text, spGetConversionErrors);
            throw new Exception("Test the text/html text/xml message.");
        }
        catch
        {
            throw;
        }
    }

Como puede ver, comenté la llamada real y simplemente añadí mi propia línea que lanzará una excepción cada vez con fines de prueba...

Edit4: @gbvb Aquí está el nuevo método:

    [WebMethod]
    [SoapHeader("authenticationHeader")]
    [WebServiceAuthentication(AuthenticationRequired = false)]
    public DataSet GetConversionErrors()
    {
        try
        {
            return Components.PWD.GetConversionErrors();
        }
        catch (Exception ex)
        {
            //PublishingManager.Publish(ex, HttpContext.Current.User.Identity.Name);
            //throw Components.SoapException.GenerateSoapException(ex, Context);

            System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
            System.Xml.XmlNode detailNode = xmlDoc.CreateNode(System.Xml.XmlNodeType.Element, System.Web.Services.Protocols.SoapException.DetailElementName.Name, System.Web.Services.Protocols.SoapException.DetailElementName.Namespace);
            detailNode.InnerText = ex.ToString();

            throw new System.Web.Services.Protocols.SoapException(ex.Message, System.Web.Services.Protocols.SoapException.ClientFaultCode, System.Web.HttpContext.Current.Request.Url.AbsoluteUri, detailNode, ex.InnerException);
        }
    }

Edit5: Lo que vio Fiddler2:

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 23 May 2012 19:25:56 GMT
Content-Length: 1208

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>500 - Internal server error.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} 
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>500 - Internal server error.</h2>
  <h3>There is a problem with the resource you are looking for, and it cannot be displayed.</h3>
 </fieldset></div>
</div>
</body>
</html>

Si alguien sabe cómo formatear bien esta sección, por favor hágalo :)

preguntado el 22 de mayo de 12 a las 20:05

"Así que seguí adelante e implementé eso, pero ahora sigo recibiendo el mismo error" Lo escuché y lo dije antes. ¿Estás seguro de que has completado implementado sus cambios y los implementó en el entorno en el que está probando? -

Además, es fundamental saber qué versión de .NET está ejecutando:

Creo que sí, estoy ejecutando los servicios web en mi "localhost" y simplemente llamándolo. Puedo configurar puntos de interrupción tanto del lado del servidor como del lado del cliente... pero cuando se detiene en el lado del cliente, la excepción real que devuelve el servidor es InvalidOperationException en lugar de SoapException. -

No es tan difícil cambiar de ASMX a WCF en la mayoría de los casos. El código del lado del cliente ni siquiera necesita saber sobre el cambio. Además, será mucho más fácil cambiar este año que cambiar dentro de cinco o diez años cuando nadie recuerde lo que solía ser ASMX. Además, como dije, ASMX no admite fallas correctamente. -

Es algo así, pero eso tiene varios años. En particular, la configuración del servicio es muchos más simple en .NET 4.0, por lo que no estoy seguro de que tenga que agregar puntos finales individuales a web.config. Si lo hiciera, probablemente solo necesitaría especificar la URL de cada punto final y poco más; el resto sería predeterminado. Además, en .NET 4.0, su proceso de compilación no necesitará actualizarlos. Usaría transformaciones web.config. -

2 Respuestas

Entonces, lo hice funcionar. Esto es lo que descubrí:

Al ver las propiedades de mi sitio web en IIS, luego elegir "Módulos", hay una entrada llamada "CustomErrorModule" que intenta procesar los errores que arroja el sitio web/servicio web.

La solución es eliminar esa entrada "CustomErrorModule" o actualizar mi archivo de configuración desde:

<httpErrors errorMode="Custom" existingResponse="Replace">

a:

<httpErrors errorMode="Custom" existingResponse="Auto">

Gracias a todos por la ayuda, me guió en la dirección correcta. (Por cierto, estoy actualizando el archivo de configuración para no tener que meterme con las cosas del módulo)

También, trabaja para aquí hay un enlace explicando esta situación.

Respondido el 13 de junio de 12 a las 22:06

Solo para reír, ¿puede intentar lanzar explícitamente una nueva SoapException() con SoapException.ClientFaultCode como el tipo de esa llamada? obviamente, tiene varias capas que podrían estar fallando en el código que muestra arriba y es fácil estropearlo (créanme, lo sé :)). Y no llame a los otros métodos como Publisher.publish... eso indicará si es la declaración del mensaje (es decir, la infraestructura ASMX) o es su código el que está interfiriendo con la excepción...

contestado el 23 de mayo de 12 a las 14:05

Los intentaré de inmediato... También intentaré lanzar una excepción regular en lugar de una SoapException. - mira

¿La edición de código parece correcta y sigues viendo el mismo problema? - gbvb

correcto, todavía viendo la misma respuesta. ¿Es por lo que respondió John Saunders sobre "ASMX no admite fallas correctamente", o esa falla no es la misma que estoy viendo? - mira

Mira este KB: support.microsoft.com/kb/942031 . y prueba la Resolución 7 ya que parece ser exactamente lo que estás viendo... :) - gbvb

No es el cliente. ¡Necesitas revisar el servidor! algo en el servidor podría haber sido mal configurado. Puede ser la resolución 4, pero en cualquier caso, verifique el servidor si permite que el servidor maneje realmente el servicio web (asmx). Ese parece ser el problema por lo que estoy viendo aquí. - gbvb

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