Over the years, I’ve written a lot of code that simple dumps out an object’s properties. Sometimes this is for debugging, sometimes it is for output to Console.WriteLine. But a lot of those cases are plain old BORING, and the only reason I end up typing in obj.foo, obj.bar, and obj.gizmo is that I was too lazy to figure out how to easily stringify an entire object at a time – so I kept doing it one property (and sub-property (and sub-sub-property ..)) at a time.
I know that ToString() is supposed to help out (in .NET at least), but you probably noticed how uncommon it is for this to be usefully implemented.
There’s a better way.
A Pretty-Printer for C# objects that’s usually Good Enough™
The simple way to dump objects that’s often good enough (but not always good enough) is to use Json.NET’s object serializer.
Add Json.NET using NuGet, then using a code snippet like the following to dump out an object named someObject
:
Console.WriteLine(
Newtonsoft.Json.JsonConvert.SerializeObject(
someObject, Formatting.Indented));
That’s pretty much it. That’s the whole trick.
Note: You can use Formatting.None
instead of Formatting.Indented
if you want a more compact output (though harder to read).
Here are a couple of reasons why is isn’t always better:
- You get the WHOLE object graph (no filtering – but see this and this)
- Fields appear in JSON in the order they appear in the object – you don’t get to change it
- Not easily massaged (e.g., do you want only a certain number of decimal places?)
- (Probably more since I just started using this…)
Useful in other languages
This hack applies to any language that supports JSON serializers and formatters. For example, in Python, check out the json module.
Examples in C#
Here is are a couple of examples using a CORS tool I was fiddling with. In these examples, the serviceProperties object is of type ServiceProperties, a class from the Windows Azure Storage SDK for .NET.
Dump Just CORS:
Newtonsoft.Json.JsonConvert.SerializeObject(
serviceProperties.Cors, Formatting.Indented);
"Cors": { "CorsRules": [ { "AllowedOrigins": [ "*" ], "ExposedHeaders": [ "*" ], "AllowedHeaders": [ "*" ], "AllowedMethods": 1, "MaxAgeInSeconds": 36000 } ] }
Dump Entire Properties object:
Newtonsoft.Json.JsonConvert.SerializeObject(serviceProperties, Formatting.Indented);
{ "Logging": { "Version": "1.0", "LoggingOperations": 0, "RetentionDays": null }, "Metrics": { "Version": "1.0", "MetricsLevel": 0, "RetentionDays": null }, "HourMetrics": { "Version": "1.0", "MetricsLevel": 0, "RetentionDays": null }, "Cors": { "CorsRules": [ { "AllowedOrigins": [ "*" ], "ExposedHeaders": [ "*" ], "AllowedHeaders": [ "*" ], "AllowedMethods": 1, "MaxAgeInSeconds": 36000 } ] }, "MinuteMetrics": { "Version": "1.0", "MetricsLevel": 0, "RetentionDays": null }, "DefaultServiceVersion": null }
To use another concrete example, consider a simple program that I wrote a while back called DumpAllWindowsCerts.cs. The program just iterates through the Certificate Store on the current machine and dumps out a bunch of information. It uses Console.WriteLine statements to do this.
To compare the old and new outputs, I jumped to the LAST Console.WriteLine statement in the file and changed it to a JsonConvert.SerializeObject statement. Here’s what happened.
Note that the old Console.WriteLine statement was very limited since the contents of these objects varied a lot, so I had kept is simple (I didn’t know what I wanted, really). But the JSON output is pretty reasonable.
————————————————– Console.WriteLine
OID = Key Usage OID = Basic Constraints [Critical] OID = Subject Key Identifier OID = CRL Distribution Points ...
————————————————– JSON.NET
{ "KeyUsages": 198, "Critical": false, "Oid": { "Value": "2.5.29.15", "FriendlyName": "Key Usage" }, "RawData": "AwIBxg==" } { "CertificateAuthority": true, "HasPathLengthConstraint": false, "PathLengthConstraint": 0, "Critical": true, "Oid": { "Value": "2.5.29.19", "FriendlyName": "Basic Constraints" }, "RawData": "MAMBAf8=" } { "SubjectKeyIdentifier": "DAED6474149C143CABDD99A9BD5B284D8B3CC9D8", "Critical": false, "Oid": { "Value": "2.5.29.14", "FriendlyName": "Subject Key Identifier" }, "RawData": "BBTa7WR0FJwUPKvdmam9WyhNizzJ2A==" } { "Critical": false, "Oid": { "Value": "2.5.29.31", "FriendlyName": "CRL Distribution Points" }, "RawData": "MDkw...9iamVjdC5jcmw=" }
…
Pingback: Stupid Azure Trick #6 – A CORS Toggler Command-line Tool for Windows Azure Blobs | Coding Out Loud
Here’s an extension to dump out an object:
https://visualstudiogallery.msdn.microsoft.com/c6a21c68-f815-4895-999f-cd0885d8774f
Pingback: unity3d - in unity how to i print a serializable class to the console? - CSS PHP