2016-05-02 4 views
0

Вот моя попытка сделать объект самосвал:Использование отражения по запросу врезается w3wp.exe процесс

using System; 
using System.Collections.Generic; 
using System.Reflection; 
using System.Text; 

namespace Inspector 
{ 
    public static class Inspector 
    { 
     public static string Inspect(this object o) 
     { 
      StringBuilder sb = new StringBuilder(); 
      InspectObject(o, sb); 
      return sb.ToString(); 
     } 

     private static void InspectObject(object o, StringBuilder sb) 
     { 
      Type objType = o.GetType(); 
      if (objType == typeof(string)) 
       sb.Append(o.ToString()); 
      else 
      { 
       try 
       { 
        IList<PropertyInfo> props = new List<PropertyInfo>(objType.GetProperties()); 

        foreach (PropertyInfo prop in props) 
        { 
         object propValue = null; 
         ParameterInfo[] ip = prop.GetIndexParameters(); 
         if (ip.Length == 0) 
         { 
          propValue = prop.GetValue(o, null); 
          InspectObject(propValue, sb); 
         } 
         else 
         { 

         } 
        } 
       } 
       catch (Exception ex) 
       { 
        sb.Append(string.Format("Exception: {0}", ex.Message)); 
       } 
      } 
     } 
    } 
} 

Когда я использую его, чтобы проверить Request (Request.Inspect()) в методе Index HomeController в аварии, w3wp.exe процесса и блок try-catch не выполняет свою работу.

Что на самом деле происходит? Microsoft говорит, что только необработанные исключения crash w3wp.exe, но я вызываю Request.Inspect(), завернутый в родительский блок try-catch;

+2

Обратите внимание, что StackOverflow (который является общим результатом рекурсии) убивает процесс и не может быть пойман ... –

ответ

1

Я не уверен, какой именно тип Request вы используете, поэтому я просто прочитал документацию класса HttpRequest. Если это не то, что вы используете, по крайней мере, я могу дать вам представление о том, что происходит:

  1. HttpRequest класс имеет свойство RequestContext типа RequestContext, так что вы звоните InspectObject для этого свойства
  2. это RequestContext имеет свойство HttpContext типа HttpContextBase, так что вы звоните InspectObject для этого свойства
  3. это HttpContextBase имеет свойство Request типа HttpRequest, который является ток Запрос, и - да - вы звоните InspectObject для этого свойства, начиная с 1. снова, потому что это тот же экземпляр

Так что это рекурсия никогда не останавливается, и вы заполняете свой стек вызовов, пока вы не получите StackOverflowException. Этот вид исключения не может быть обработан в вашем блоке catch, потому что стек (и вместе с ним весь процесс) уже поврежден.


Чтобы решить эту проблему вам нужно какое-то обнаружение рекурсии, который говорит вам, если вы пытаетесь осмотреть объект, который уже проверен. Затем вы можете остановить рекурсию в этот момент.
Альтернативно, вы можете остановить рекурсию на определенной глубине. Конкретное решение зависит от того, для чего вам нужна вся эта информация.

+0

Это правда, хотя 'Request.RequestContext.HttpContext.Request! = Request'. Я ограничил глубину до 10, и процесс больше не разбился. – Paul

Смежные вопросы