2010-06-18 12 views
5

Básicamente quiero tomar el siguiente: alt text¿Cómo se accede al error de origen, al archivo de origen y al número de línea de una excepción para usar en una página de error personalizada?

y hacer que coincida con el estilo del resto de la aplicación.

Estoy creando una página de error personalizada en mi proyecto basado en C# y quiero que sea capaz de mostrar la misma información que se muestra en la página de error predeterminada de ASP.NET. Desde el toqueteo con el reflector puedo ver que esto se genera a través de HttpException.GetHtmlErrorMessage(), pero cuando trato de usar esto en mi excepción, devuelve null.

+0

¿Quiere decir que desea mostrar la misma información de error técnica exacta (el público objetivo de las cuales es la gente que construyó el sitio para que puedan arreglar lo que está mal con él) con el mismo aspecto y -¿Te sientes como el resto del sitio? – apollodude217

Respuesta

1

que no es necesario añadir un filtro a hacer caso agarrar, simplemente manejar Application_Error en global.asax.cs. Server.GetLastError() tendrá la información de excepción

Sí, erm ... No. El error que se muestra en la pregunta original muestra un error de análisis/compilación - estos errores ocurren en la tubería HttpHandler para ASP .NET (Filtro ISAPI en versiones anteriores de IIS), es decir, antes de, su aplicación es un evento iniciado, por lo que antes de cualquiera de los eventos en Global.asax.

Aunque puede especificar una página de error personalizada (en web.config, machine.config o metabase de IIS), estos solo pueden ser archivos HTML.

1) si solo está interesado en las excepciones que surgen en su código (es decir, su código se compila, pero se lanza una excepción), puede usar la sugerencia de Dan desde arriba y manejar el evento Application_Error en Glocal.asax.

Si desea manejar las excepciones de ASP.NET (por ejemplo, errores de análisis/compilación, errores de configuración de archivos, etc.), deberá conectar (o reemplazar) el HttpHandler de ASP.NET.

Puede ajustar el controlador existente escribiendo el suyo, y capturando cualquier excepción, y luego redirigiendo a otra página de error.

Debería especificar su controlador en su archivo web.config (o machine.config si es un controlador global).

Hay algunos buenos tutoriales en la web sobre cómo hacer esto. Trate de comenzar aquí: http://msdn.microsoft.com/en-us/library/f3ff8w4a(VS.71).aspx

(problema principal es: para atrapar errores de análisis/compilación que necesita para escribir un controlador/filtro, que es un nivel por encima de el controlador de ASP.NET/filtro (creo)).

Espero que esto ayude, Dourn.

0

Nunca he intentado hacer esto, pero todos los errores de IIS se registran en el registro de eventos. Podría tratar de leer el último error del registro de eventos y mostrarlo si ya está escrito.

También querrá agregar un filtro a su evento para asegurarse de que está mostrando eventos de su aplicación y que no hay otros eventos de error dentro de un período de tiempo significativo.

+1

Esto es, por supuesto, complicado, especialmente si está ejecutando la aplicación en un servidor compartido. No solo dudo que tenga acceso al registro de eventos, sino que también otra aplicación podría haber registrado otro evento en el tiempo transcurrido entre el error y la recuperación de una entrada de evento. En realidad, tu propia aplicación también podría hacer eso. – ErikHeemskerk

+0

No necesita agregar un filtro para capturar eventos, simplemente maneje Application_Error en global.asax.cs. Server.GetLastError() tendrá la información de excepción. – dvallejo

+0

Como dice Erik, no hay manera de saber con certeza qué error se muestra en el registro: no hay forma de saber qué error está causando que este usuario en particular de esta aplicación vea la página de error. – apollodude217

2

Iain,

He utilizado este código con el fin de hacer algo similar en una página de error personalizada. No estoy seguro de si que muestra la región de código fuente exacta que causó el error es posible utilizar el objeto de excepción, pero yo era capaz de utilizar el seguimiento de la pila, que incluye los números de línea y los nombres de método:

If Not IsPostBack Then 
    Dim ex As Exception = Server.GetLastError().GetBaseException() 
    lblExceptionMessage.Text = ex.Message.ToString() 
    lblStackTrace.Text = ex.StackTrace().Replace(System.Environment.NewLine, "<br />") 
End If 

Puede también use ex.TargetSite para obtener solo el nombre del método que arrojó la excepción.

HTH,

Mike

2

Esta respuesta es un poco viejo, pero ninguna de las respuestas existentes realmente hacer frente a la pregunta original. Estaba buscando algo similar, y no pude encontrar nada, así que aquí está mi solución rápida y sucia.

En primer lugar, es necesario descomponer realmente el trazado de la pila y obtener el marco de nivel superior.

var st = new System.Diagnostics.StackTrace(this.Exception, true); 
var frame = st.GetFrame(0); 

Entonces, necesita leer el archivo que el bastidor se refiere a (nota, esto sólo funcionará, creo que, si los archivos de AP están disponibles) y averiguar qué líneas que desea mostrar. Este es un método que, si se aprueba, enviará un diccionario con las posibles líneas. Luego puedes embellecerlo como quieras.

public Dictionary<int, string> GetFileInfo(Exception ex, int linesBefore, int linesAfter) 
    { 
     Dictionary<int, string> sb = new Dictionary<int, string>(); 
     var st = new System.Diagnostics.StackTrace(ex, true); 
     var frame = st.GetFrame(0); 

     using (System.IO.StreamReader file = new System.IO.StreamReader(frame.GetFileName())) 
     { 
      if (file == null) 
       return sb; 

      int counter = 0; 
      int line = frame.GetFileLineNumber(); 
      int lastline = line + linesAfter; 
      int firstline = line - linesBefore; 

      while (!file.EndOfStream && counter < lastline) 
      { 
       string str = file.ReadLine(); 
       if (counter > firstline && !string.IsNullOrWhiteSpace(str)) 
        sb.Add(counter, str); 
       counter++; 
      } 
     } 

     return sb; 

    } 
+1

Esto funciona bastante bien, pero encontré que obtener st.GetFrame (0) a menudo devolvía algo mucho más alto de lo que quería, como SqlConnection.OnError (... Lo modifiqué para pasar por st.GetFrames() hasta que Encontré marcos donde GetFileName()! = null. Eso me devolvió los marcos que quería, los que tenían referencias a las líneas de código fuente en el archivo PDB. – Lane

+0

Además, comience el contador en 1 ya que la numeración de la línea de archivos comienza en 1. – Lane

Cuestiones relacionadas