ToDebugString() – give me some debug info about my object, e.g. Request.Url

by Oliver 16. September 2011 20:06

Lately, I was having trouble debugging certain parts of my code in Visual Studio, and all I wanted to know was the value of some variable at some point in time. Well, I’d use some logging if I could just get at that value easily. But for some objects I don’t really know what I’m looking for or where I should be looking for it. So just give me the values of all the members of that object, will ya? And could you recurse that? But no deeper than 3 levels, alright? Or let’s say… 5?

public static string ToDebugString(this object obj, int maxdepth, int depth=0)
{
    if (obj == null)
        return "null";
 
    if (obj is IConvertible)
        return obj.ToString();
 
    if (depth >= maxdepth)
        return "...";
 
    var sb = new StringBuilder();
 
    if (depth > 0)
        sb.AppendLine();
 
    foreach (var propertyInfo in obj.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance))
    {
        sb.Append(new string(' ', 2*depth)).Append(propertyInfo.Name).Append(": ");
        try
        {
            var value = propertyInfo.GetValue(obj, new object[0]);
            sb.AppendLine(ToDebugString(value, maxdepth, depth + 1));
        }
        catch (Exception ex)
        {
            sb.AppendLine(string.Format("[{0}]", ex.Message));
        }
    }
 
    // remove newline from end of string
    var newLine = Environment.NewLine;
    if (sb.Length >= newLine.Length)
        sb.Replace(newLine, "", sb.Length - newLine.Length, newLine.Length);
 
    return sb.ToString();
}
With this little helper I can now simply call anyobject.ToDebugString(4 /* maxdepth */) and I get a nicely formatted debug view of that object; e.g. Request.Url.ToDebugString(3) gives me:
AbsolutePath: /logg.aspx
AbsoluteUri: http://localhost:55235/logg.aspx
Authority: localhost:55235
Host: localhost
HostNameType: Dns
IsDefaultPort: False
IsFile: False
IsLoopback: True
IsUnc: False
LocalPath: /logg.aspx
PathAndQuery: /logg.aspx
Port: 55235
Query:
Fragment:
Scheme: http
OriginalString: http://localhost:55235/logg.aspx
DnsSafeHost: localhost
IsAbsoluteUri: True
Segments:
Length: 2
LongLength: 2
Rank: 1
SyncRoot:
Length: 2
LongLength: 2
Rank: 1
SyncRoot: ...
IsReadOnly: False
IsFixedSize: True
IsSynchronized: False
IsReadOnly: False
IsFixedSize: True
IsSynchronized: False
UserEscaped: False
UserInfo:

Nice Smile

Right now this method chokes on indexed properties but once I’ll need it I’ll go and look for a way to include them. It also chokes any exceptions on the way to just get the job done.

Happy coding!

Comments are closed

About Oliver

shades-of-orange.com code blog logo I build web applications using ASP.NET and have a passion for javascript. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our children. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton

shades-of-orange.com code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.