CESAR DE LA TOR... 的个人资料Blog de CESAR DE LA TORR...照片日志列表更多 ![]() | 帮助 |
|
1月3日 Gestion de Excepciones 'custom' en Servicios Web básicos (ASMX)La gestión de excepciones en Servicios Web básicos (ASMX) no es igual que la El problema viene originado porque sin utilizar la clase SoapException, el diccionario 'Data' y la 'innerException' de una excepción normal de .NET (CLR), no se serializan ni se transmiten por lo tanto a la aplicación cliente que consume el Web Service. Básicamente, como trabajo yo para gestionar las excepciones de servicios Web
Ejemplo en C# de creación de excepción en método de componente de negocio: //(CDLTLL)Si no tiene acceso autorizado, lanzamos una excepción de seguridad. if (!authorized) { string infoCustom = "Lo que quiera poner"; ApplicationException appEx = new ApplicationException(string.Format(CultureInfo.CurrentCulture, global::Empresa.AplicacionA.Modulo1.ComponentesAplicacion.Properties.Resources.BllEx002, userName, classMethod, requiredPermissionName)); appEx.Data.Add("ExceptionId", "BllEx002"); appEx.Data.Add("UserName", userName); appEx.Data.Add("InfoCustom", infoCustom); throw appEx; } Lo importante es que estoy metiendo los datos que yo quiera dentro del objeto Data que está a su vez dentro del objeto Exception. Si la excepción es causada por el sistema (SqlException, por ejemplo), pues tendrá otra información relativa al error dentro de la excepción.
[WebMethod] public bool TransferenciaBfll_RealizarTransferencia(string numCuentaOrigen, string numCuentaDestino, int cantidad) { try { return TransferenciaBfll.RealizarTransferencia(numCuentaOrigen, numCuentaDestino, cantidad); } catch (Exception ex) { ProcesarExcepcionParaSoap(ex); return false; } } En ese WebMethod solamente se llama a un método de un componente de negocio y en caso de haber alguna excepción, la procesamos en el Catch. ¿Qué hacemos en ese método llamado ProcesarExcepcionParaSoap(ex), pues precisamente convertir la excepción normal de .NET en una SoapException y cambiar los datos internos de unas colecciones de datos a otras. Aquí tenéis lo que hace este método ProcesarExcepcionParaSoap(ex): private void ProcesarExcepcionParaSoap(Exception ex) { //(CDLTLL) Si tenemos detalles de la excepción de la transferencia if (ex.Data["ExceptionId"] != null) { //(CDLTLL) Hace falta crear la SoapException si se quiere transmitir //(CDLTLL) detalles al cliente, porque el diccionario 'Data' no se serializa en XML del WS //(CDLTLL) ni tampoco se serializa la innerException.
//(CDLTLL) Construimos el detalle de la excepción SOAP System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); System.Xml.XmlNode node = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace); //Construimos detalles específicos de la SoapException.
// Añadimos un nodo hijo XML de detalle, con un atributo por cada propiedad a controlar. System.Xml.XmlNode detalles = doc.CreateNode(XmlNodeType.Element, "DetallesExcepcionTransferencia", http://tempuri.org/); XmlAttribute attrExceptionId = doc.CreateAttribute("e", "ExceptionId", "http://tempuri.org/"); attrExceptionId.Value = ex.Data["ExceptionId"].ToString(); detalles.Attributes.Append(attrExceptionId);
if (ex.Data["AccountNum"] != null) { XmlAttribute attrAccountNum = doc.CreateAttribute("a", "AccountNum", "http://tempuri.org/"); attrAccountNum.Value = ex.Data["AccountNum"].ToString(); detalles.Attributes.Append(attrAccountNum); } if (ex.Data["UserName"] != null) { XmlAttribute attrAccountNum = doc.CreateAttribute("u", "UserName", "http://tempuri.org/"); attrAccountNum.Value = ex.Data["UserName"].ToString(); detalles.Attributes.Append(attrAccountNum); }
if (ex.Data["ClassMethod"] != null) { XmlAttribute attrAccountNum = doc.CreateAttribute("c", "ClassMethod", "http://tempuri.org/"); attrAccountNum.Value = ex.Data["ClassMethod"].ToString(); detalles.Attributes.Append(attrAccountNum); } node.AppendChild(detalles); //Lanzamos la excepción SOAP con DETALLES(DATA). SoapException se = new SoapException(ex.Message, SoapException.ClientFaultCode, Context.Request.Url.AbsoluteUri, node); throw se; } else { //Lanzamos la excepción BASICA sin detalles. throw ex;
} } (3).- Capturas la excepción en la aplicación cliente y accedes a las propiedades Más en detalle, en el cliente, lo que hacemos es crear una instancia del objeto proxy y en el caso de detectar alguna excepción, procesarla en el CATCH: try { // Se instancia el WebService del Cliente para realizar la llamada Modulo1WS modulo1Ws = new Modulo1WS();
// Proporcionamos las Credenciales actuales modulo1Ws.Credentials = System.Net.CredentialCache.DefaultCredentials; return modulo1Ws.TransferenciaBfll_RealizarTransferencia(numCuentaOrigen, numCuentaDestino, cantidad); } catch (SoapException soapEx) { ExcepcionesUtil.ProcesarExcepcionSOAPGestionada(soapEx); return false; } Aquí también, el trabajo realmente se hace en el método ProcesarExcepcionSOAPGestionada(soapEx). Básicamente, dentro de este método se accede a nuestros valores/propiedades de la siguiente forma: string accNum = soapEx.Detail.FirstChild.Attributes["a:AccountNum"].Value.ToString();
Como se puede observar, el procesamiento de excepciones custom para Servicios-Web no es algo inmediato. Tampoco es que sea muy difícil, pero se complica. J |
|
|