2010-01-26 18 views
7

Estoy construyendo la aplicación web ASP.NET estándar de 3 niveles, pero estoy luchando sobre dónde hacer ciertas cosas, específicamente el manejo de excepciones.¿Cómo y dónde manejar las excepciones en una aplicación web de 3 niveles? Específicamente SQL Base de excepciones

He intentado echar un vistazo en la web para encontrar algunos ejemplos, pero no encuentro ninguno que llegue hasta un proyecto completo que muestra cómo todo se vincula.

En mi nivel de datos me estoy conectando a SQL Server y haciendo algunas cosas. Sé que necesito detectar excepciones que podrían surgir como resultado, pero no estoy seguro de dónde hacerlo.

Por lo que he leído, debería hacerlo en el nivel UI, pero en ese caso no estoy seguro de cómo asegurar que la conexión a la base de datos esté cerrada. ¿Alguien puede aclarar cómo hacer esto? Además, si alguien sabe dónde podría encontrar un ejemplo de aplicación web de 3 niveles que siga las mejores prácticas, también sería genial.

gracias

Respuesta

6

No hay respuestas fáciles o patrones que garanticen el éxito. Al igual que su estrategia de validación , su estrategia exacta de manejo de excepciones es específica para su situación exacta, y suele ser una compensación entre el tiempo y la exhaustividad. Sin embargo, hay algunos buenos consejos que podemos dar:

  • No oculte nunca el stack-trace; nunca uses "Rethrow" a menos que por motivos de seguridad quieras ocultar lo sucedido.
  • No sientas que necesitas manejo de errores en todas partes. Por defecto, en los niveles inferiores, permitir que el error real se filtre hasta el nivel superior no es malo.La interfaz de usuario/controlador es donde realmente tiene que decidir cómo reaccionar a algo que va mal.
  • En todo momento, como usted mismo, qué es exactamente lo que quiere que suceda si algo sale mal. A menudo, no podrás pensar en nada mejor que simplemente dejar que suba a la capa superior o incluso a la máquina del cliente. (aunque en el turno de producción de informes detallados). Si este es el caso, simplemente déjalo ir.
  • Asegúrese de desechar los recursos no administrados (Cualquier cosa que implemente IDisposable). Su acceso a los datos es un gran ejemplo. O bien (Un) Llame .Dispose() para su (especialmente) de conexión, comandos, etc. datareader en el bloque Finalmente, o (B ) utilizan el Using Syntax/Pattern la que se asegura de que sucede Eliminación adecuada.
  • Busque los lugares donde es probable que haya errores y en los que pueda buscar ciertos errores, reaccione (volviendo a intentarlo, espere un segundo intento, pruebe esa acción de otra manera, etc.) y luego tenga suerte. Gran parte de su manejo de excepciones es hacer que el éxito suceda, no solo para reportar fallas correctamente.
  • En la capa de datos, debe considerar qué hacer si algo sale mal en medio de un proceso de varios pasos. Puede permitir que el error real se filtre, pero esta capa debe manipularse después de un error. A veces querrás usar transacciones.
  • En una situación asíncrona (ya sea (A.) debido a múltiples hilos o (B.) porque la lógica comercial se procesa por separado en "máquinas de tareas" y tal y actuamos más adelante), en particular necesita tener un plan para errores de registro
  • Prefiero ver el "código de manejo de errores" en el 25% de su aplicación que el 100%. El 100% significa que probablemente quisiste que pareciera que tienes el manejo de errores. 25% significa que pasó tiempo manejando excepciones donde realmente necesitaban ser manejadas.
+0

gracias por la respuesta. ¿Cuáles son sus pensamientos sobre el manejo de SQLExceptions? Para los errores planteados dentro de sproc, ¿los detectaría en el DAL y arrojaría un error personalizado aquí o alguna alternativa? – Nick

+1

En mi DAL actual (más una herramienta * DA *, que paso a mis objetos comerciales que también son objetos mitad DAL) capto y trato automáticamente con algunos errores específicos (como el error # 1205 de víctima de interbloqueo. Veo eso, lo intento una vez más), pero dejo que la mayoría de los errores se filtren. Algunas veces el objeto comercial puede hacer algo inteligente con ese error; si no, dejo que se filtre. En mi DAL pronto voy a registrar automáticamente el error y el texto y los parámetros del comando sql automáticamente. Consideré amablemente agregar el texto sql al mensaje de error, pero eso es una preocupación de seguridad. –

+0

Solo detecte errores en sus sprocs/udf si puede (** A **) recuperar/reaccionar/tal vez tener éxito, o si (** B **) puede mejorar la información de error que se filtra. Por lo tanto, el valor predeterminado no es el manejo de errores en sproc/udf, pero a veces se agrega la entrega de errores. –

1

Sólo un punto secundario que puede dirigir su pensamiento: si tiene cualquier tipo de volumen que pueden dar lugar a problemas de concurrencia (interbloqueo) que quiere que su aplicación que detecta que el error SQL determinada y vuelva a intentar la operación (por ejemplo, transacción). Eso aboga por un manejo de excepciones en los niveles de datos o de negocios.

-Krip

+0

aplausos por el comentario Krip , lo tendremos en cuenta para esas situaciones – Nick

1

creo que es la mejor práctica para manejar excepciones en el último momento responsable. Esto generalmente significa en el nivel de IU (es decir, el controlador en una aplicación MVC o en el código subyacente en una aplicación asp.net tradicional). Es en este nivel alto que su código "sabe" lo que el usuario está preguntando, y lo que debe hacerse si algo no funciona.

El manejo de excepciones en la parte inferior de la pila de llamadas generalmente provoca que el código de llamada no sea capaz de manejar adecuadamente las situaciones excepcionales.

en su nivel de datos, debe utilizar los patrones estándar (por ejemplo, la using statement para IDisposables como el SqlConnection), excepciones de documentos que conoce puede producirse (no hacer esto porque de la memoria u otros casos raros), y luego dejarlos fluir por la pila de llamadas cuando lo hacen. Como máximo, es posible que desee capturar esas excepciones y envolverlas en un solo tipo de excepción, en situaciones en las que las personas que llaman tengan que manejar MUCHAS excepciones.

Si necesita "limpiar" algo antes de dejar pasar las excepciones, siempre puede usar un finally block para limpiar. No es necesario que catch para usar un bloque finally.

No conozco ningún ejemplo de sitios web pequeños que estén diseñados para resaltar el manejo de excepciones adecuado, lo siento.

+0

¿Está bien esperar a que la recolección de basura cierre la conexión usando la instrucción using? – Nick

+1

No, desea cerrar la conexión (a) inmediatamente cuando finalice, o (b) en el bloque Finalmente, o utilice la sintaxis/patrón de Uso para que esto ocurra automáticamente. Desarrollaré sobre eso. . . –

+0

@nick verifique el enlace en mi respuesta para la declaración 'using'. – Will

Cuestiones relacionadas