Here is my try to make an object dumper:
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));
}
}
}
}
}
When I am using it to inspect Request
(Request.Inspect()
) in HomeController's Index method, w3wp.exe process crashes and try-catch block doesn't do it's job.
What is actually happening? Microsoft says, that only unhandled exceptions crash w3wp.exe, but I am calling Request.Inspect()
wrapped into parent try-catch block;
I'm not sure what exact type of Request
you use, so I just read the documentation of the HttpRequest class. If that's not what you are using, at least I can give you an idea of what's happening:
HttpRequest
class has a property called RequestContext
of type RequestContext
, so you call InspectObject
for that propertyRequestContext
has a property HttpContext
of type HttpContextBase
, so you call InspectObject
for that propertyHttpContextBase
has a property called Request
of type HttpRequest
which is the current request, and - yes - you call InspectObject
for that property, starting at 1. again because it's the same instanceSo this recursion never stops and you fill your call stack until you get a StackOverflowException
. This kind of exception cannot be handled in your catch
block because the stack (and with it the whole process) is corrupted already.
To solve this you need some kind of recursion detection that tells you if you try to inspect an object that has already been inspected. Then you can stop the recursion at that point.
Alternativly you can stop the recursion at a certain depth. The specific solution depends on what you need all that information for.