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

by Oliver Fri, September 16 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!

Tags:

.NET | C# | Debugging | Software development | Tips & Tricks | Visual Studio | developer

MSBuild and Visual Studio 2010 generate different DLLs

by Oliver Tue, September 06 2011 22:18

Recently, we encountered a quite surprising behavior of MSBuild – the continuous integration build of our new collaborative Todo Management app (we hope to go into beta soon!) would produce a broken version whereas the local build with VS2010 was all smooth and well. Our admin and tester already posted about this problem over at his blog: MSBuild does not build like Visual Studio 2010.

The exception message finally led me down the right path:

Server Error in '/' Application.

No constructors on type 'Teamaton.TodoCore.Repositories.TodoRepositoryJson' can be found with 'Public binding flags'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: Autofac.Core.DependencyResolutionException: No constructors on type 'Teamaton.TodoCore.Repositories.TodoRepositoryJson' can be found with 'Public binding flags'.

The TodoRepositoryJson is a type we used at the very beginning of our development to quickly get started using a JSON document as data store. Later we switched to SQLite, so now we have another implementation: TodoRepositoryDb. Both implement the same interface ITodoRepository.

Turns out, the Autofac type registering code was the culprit:

   1: var builder = new ContainerBuilder();
   2: builder.RegisterAssemblyTypes(typeof (Todo).Assembly)
   3:     .Where(t => t.Name.Contains("Repository"))
   4:     .AsImplementedInterfaces()
   5:     .InstancePerLifetimeScope();

What worked with Visual Studio, didn’t work with MSBuild: obviously – well, now it is – both ITodoRepository implementations were registered with Autofac, and while Autofac’s assembly scanning delivered them in the order we assumed from the DLL built with VS  – first, TodoRepositoryJson, and second, TodoRepositoryDb, thus overriding the first registration – MSBuild seems to build a DLL which returns the inverse order! Very strange.

Honestly, I’m not familiar with the anatomy of DLLs and surprised by this result. But it’s the only explanation I’ve found so far.

Well, the solution to the problem is, of course, to care more about what we register with Autofac and in which order.

Happy coding,

Oliver

Tags: , , ,

Build | C# | Software development | Visual Studio

Disable Dynamic Ports

by Stefan Fri, January 29 2010 11:51

Macht das Leben leichter:

Tags:

SCM (SVN, GIT, ..) | Visual Studio

VS2008 Code Snippet zum Repeater-Befuellen

by Stefan Mon, September 14 2009 18:26

Wir befuellen ja haeufig im Frontend einen Repeater. Das einfaedeln der DataSource und das Erstellen und Verknuepfen des EventHandlers fuer ItemDataBound bekommt man mit IntelliSense innerhalb weniger Sekunden hin. Aber wenn man dann den Befuell-Code schreibt, geht es immer wieder los: Wie waren gleich nochmal die ersten 3 Zeilen? Damit ist jetzt Schluss. Einfach die Datei "repeater.snippet" in "Documents/Visual Studio 2008/Code Snippets/Visual C#/My Code Snippets" des Nutzers mit dem man VS ausfuehrt kopieren. Leider zeigt die ReSharper-IntelliSense den Shortcut nicht an, funktionieren tut es trotzdem. Man tippe: rpt [ESC] [TAB]

Der Rest versteht sich von selbst:

repeater.snippet (1,03 kb)

Tags:

Productivity | Tips & Tricks | Visual Studio

Configuration mit configSource auslagern - Copy always

by Oliver Sat, September 05 2009 10:01

Eine kleine Notiz für die Zukunft:

Wenn man eine Configuration-Section aus einer *.config-Datei in eine eigene Datei auslagert, so wie neulich geschehen für die NHibernate-Konfiguration, dann sollte man die "Copy to Output Directory"-Option auf "Copy Always" setzen:

<!-- Lokal eine passende NH.config anlegen -->
<hibernate-configuration configSource="NH.config" />



Ansonsten bekommt man nämlich eine der folgenden ähnliche Fehlermeldung:

System.Configuration.ConfigurationErrorsException: Die configSource-Datei "NH.config" kann nicht geöffnet werden.
(G:\Projects\Camping.Info\Tests\bin\Debug\Tests.dll.config line 12)

Oliver

Tags:

Software development | Tips & Tricks | Visual Studio

ASP.NET Debugging und .NET Debugging

by robert Thu, October 02 2008 19:32

um vernünftig debuggen zu können, ist es nötig das Exception in Visual Studio, unter "Debug"->"Exceptions" "Common Language Runtime Exception" zu aktivieren. Ist jedoch "Enable Just My Code" (unter "Tools"->"Options" und dann im Bereich Debugging) nicht angewählt...

enable just my code 

... dann fehlt im Exeptions Windows ...

exceptions-dialog 

... die "User-unhandeld" Spalte.

exceptions-dialog 2 

etwas unerklärlich, aber per Default war bei uns (Oliver und mir) anscheinend

  • "Thrown" für Common Language Runtime Exceptions nicht ausgewählt
  • Nachdem "Thrown" expliziet aktiviert wurde, sprang der Debugger in alle Exceptions auch "User handled" Exceptions. Also auch in evil "Try Catch" Blöcke.

Die Lösung ist es nun "Enable Just My Code" zu aktivieren:

enable just my code checked

Vielleicht hilft es :-)

Tags:

Visual Studio