在 Request 上使用反射会导致 w3wp.exe 进程崩溃
Using reflection on Request crashes w3wp.exe process
这是我制作对象转储器的尝试:
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));
}
}
}
}
}
当我在 HomeController 的 Index 方法中使用它检查 Request
(Request.Inspect()
) 时,w3wp.exe 进程崩溃并且 try-catch 块没有完成它的工作。
到底发生了什么?微软说,只有未处理的异常会崩溃 w3wp.exe,但我调用 Request.Inspect()
包装到父 try-catch 块中;
我不确定您使用的 Request
的确切类型,所以我只是阅读了 HttpRequest class 的文档。如果那不是您正在使用的,至少我可以让您了解正在发生的事情:
-
HttpRequest
class 有一个 属性 称为 RequestContext
类型 RequestContext
,所以你调用 InspectObject
[=48] =]
- 这个
RequestContext
有一个类型 HttpContextBase
的 属性 HttpContext
,所以你为那个 属性[=40= 调用 InspectObject
]
- 此
HttpContextBase
有一个名为 Request
的 HttpRequest
类型的 属性,它是 当前请求,并且 - 是的- 你再次从 1 开始为 属性 调用 InspectObject
因为 它是同一个实例
所以这个递归永远不会停止,你会填满你的调用堆栈,直到你得到 WhosebugException
。这种异常无法在您的 catch
块中处理,因为堆栈(以及整个过程)已经损坏。
要解决这个问题,您需要某种递归检测,如果您尝试检查已经检查过的对象,它会告诉您。然后你可以在那个点停止递归。
或者,您可以在一定深度停止递归。具体解决方案取决于您需要所有这些信息的目的。
这是我制作对象转储器的尝试:
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));
}
}
}
}
}
当我在 HomeController 的 Index 方法中使用它检查 Request
(Request.Inspect()
) 时,w3wp.exe 进程崩溃并且 try-catch 块没有完成它的工作。
到底发生了什么?微软说,只有未处理的异常会崩溃 w3wp.exe,但我调用 Request.Inspect()
包装到父 try-catch 块中;
我不确定您使用的 Request
的确切类型,所以我只是阅读了 HttpRequest class 的文档。如果那不是您正在使用的,至少我可以让您了解正在发生的事情:
-
HttpRequest
class 有一个 属性 称为RequestContext
类型RequestContext
,所以你调用InspectObject
[=48] =] - 这个
RequestContext
有一个类型HttpContextBase
的 属性HttpContext
,所以你为那个 属性[=40= 调用InspectObject
] - 此
HttpContextBase
有一个名为Request
的HttpRequest
类型的 属性,它是 当前请求,并且 - 是的- 你再次从 1 开始为 属性 调用InspectObject
因为 它是同一个实例
所以这个递归永远不会停止,你会填满你的调用堆栈,直到你得到 WhosebugException
。这种异常无法在您的 catch
块中处理,因为堆栈(以及整个过程)已经损坏。
要解决这个问题,您需要某种递归检测,如果您尝试检查已经检查过的对象,它会告诉您。然后你可以在那个点停止递归。
或者,您可以在一定深度停止递归。具体解决方案取决于您需要所有这些信息的目的。