What is the best way to dump entire objects to a log in C#?
So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple
? objectname
Will give me a nicely formatted 'dump' of the object.
Is there an easy way to do this in code, so I can do something similar when logging?
c# visual-studio debugging object logging
add a comment |
So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple
? objectname
Will give me a nicely formatted 'dump' of the object.
Is there an easy way to do this in code, so I can do something similar when logging?
c# visual-studio debugging object logging
In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23
This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20
add a comment |
So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple
? objectname
Will give me a nicely formatted 'dump' of the object.
Is there an easy way to do this in code, so I can do something similar when logging?
c# visual-studio debugging object logging
So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple
? objectname
Will give me a nicely formatted 'dump' of the object.
Is there an easy way to do this in code, so I can do something similar when logging?
c# visual-studio debugging object logging
c# visual-studio debugging object logging
edited Jan 18 at 4:07
Matas Vaitkevicius
32.4k15161172
32.4k15161172
asked Dec 11 '08 at 17:58
Dan Esparza
19.7k2488121
19.7k2488121
In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23
This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20
add a comment |
In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23
This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20
In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23
In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23
This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20
This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20
add a comment |
12 Answers
12
active
oldest
votes
You could base something on the ObjectDumper code that ships with the Linq samples.
Have also a look at the answer of this related question to get a sample.
Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
– Dan Esparza
Dec 11 '08 at 18:24
Doesn't seem to work for XmlDocuments...
– John Hunter
Jul 2 '09 at 13:42
4
It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
– Konrad Morawski
Sep 20 '12 at 6:57
3
nuget package for ObjectDumper is now available. It also provides an extension methodDumpToString
andDump
toObject
class. Handy.
– IsmailS
Jun 17 '15 at 9:43
1
w3wp.exe
crashes when I attempt to useObjectDumper
likeRequest.DumpToString("aaa");
– Paul
May 2 '16 at 15:39
add a comment |
For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).
using Newtonsoft.Json;
public static class F
{
public static string Dump(object obj)
{
return JsonConvert.SerializeObject(obj);
}
}
Then in your Immediate Window
,
var lookHere = F.Dump(myobj);
lookHere will auto-show up in the Locals
window prepended with a $ or you can add a watch to it. On the right hand side of the Value
column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.
I am using Visual Studio 2013.
2
SerializeObj -> SerializeObject?
– Wiseman
Oct 27 '14 at 12:07
Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
– Восилей
Apr 23 at 17:45
add a comment |
I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:
private string ObjectToXml(object output)
{
string objectAsXmlString;
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
try
{
xs.Serialize(sw, output);
objectAsXmlString = sw.ToString();
}
catch (Exception ex)
{
objectAsXmlString = ex.ToString();
}
}
return objectAsXmlString;
}
You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.
2
In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
– Nikita G.
Nov 10 '13 at 9:14
I keep getting from this:Failed to access type 'System.__ComObject' failed
. Noob to c#, would appreciate help.
– GuySoft
Oct 18 '14 at 18:50
1
@GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
– Bernhard Hofmann
Oct 20 '14 at 9:15
@BernhardHofmann Thanks will look in to it
– GuySoft
Oct 20 '14 at 12:35
@BernhardHofmann Yes, seems that way :-/
– GuySoft
Oct 23 '14 at 13:31
|
show 1 more comment
I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.
Example usage:
var model = new TestModel();
Console.WriteLine(model.Dump());
and output:
{
Int: 1,
String: One,
DateTime: 2010-04-11,
Guid: c050437f6fcd46be9b2d0806a0860b3e,
EmptyIntList: ,
IntList:
[
1,
2,
3
],
StringList:
[
one,
two,
three
],
StringIntMap:
{
a: 1,
b: 2,
c: 3
}
}
1
It doesn't work for fields. The OP was explicitly asking about "entire objects".
– Konrad Morawski
Sep 20 '12 at 7:04
4
He didn't say fields
- he saidentire objects
, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple? objectname
will give me a nicely formatted 'dump' of the object").? objectname
prints out all the fields as well.This has been immensely helpful - one of my most used extension methods to date
- I'm not questioning that it's useful, only that it dumps entire objects.
– Konrad Morawski
Sep 20 '12 at 8:24
2
@KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
– mythz
Sep 20 '12 at 9:08
1
@mythz yes of course you need to prevent a stack overflow (eg. everyInt32
field has aMaxValue
field, which is anInt32
itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one),? objectname
in theImmediate Window
does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
– Konrad Morawski
Sep 20 '12 at 9:33
2
-1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
– user565869
Jul 14 '14 at 19:26
|
show 2 more comments
You could use Visual Studio Immediate Window
Just paste this (change actual
to your object name obviously):
Newtonsoft.Json.JsonConvert.SerializeObject(actual);
It should print object in JSON
You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes ("
) with "
and newlines (rn
) with empty space, then remove double quotes ("
) from beginning and end and paste it to jsbeautifier to make it more readable.
UPDATE to OP's comment
public static class Dumper
{
public static void Dump(this object obj)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
}
}
this should allow you to dump any object.
Hope this saves you some time.
Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
– Dan Esparza
Jun 23 '15 at 15:38
@DanEsparzaConsole.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual));
? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
– Matas Vaitkevicius
Jun 23 '15 at 15:52
1
FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
– Walter
Aug 31 '16 at 1:00
add a comment |
Here is a stupidly simple way to write a flat object, nicely formatted:
using Newtonsoft.Json.Linq;
Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());
What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject
, and then converted to JSON string by ToString
. (And of course a JSON string is a very nice representation of a simple object, especially since ToString
will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using +
to concat a string and an object), but I kinda like to specify it here.
3
JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
– Tertium
Aug 23 '16 at 23:04
add a comment |
You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):
MyObject
Property1 = value
Property2 = value2
OtherObject
OtherProperty = value ...
add a comment |
What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.
add a comment |
I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.
add a comment |
Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel = 0)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().IsPrimitive)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
bool ImplementsDictionary(Type t)
{
return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
}
}
1
this will die horribly if you have aDate
property in your inner object ... just saying ...
– Noctis
Sep 7 '17 at 4:43
add a comment |
You can write your own WriteLine method-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
Use it like-
WriteLine(myObject);
To write a collection we can use-
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
The method may look like-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
else if (t.GetProperties().Any())
{
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
}
Using if, else if
and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.
Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
– Dan Esparza
Mar 1 '16 at 14:50
@DanEsparza Thanks to show me the way to be more specific.
– Ariful Islam
Mar 2 '16 at 6:33
add a comment |
Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:
/// <summary>
/// Based on: https://stackoverflow.com/a/42264037/6155481
/// </summary>
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
// TODO: Prevent recursion due to circular reference
if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
{
// In ObjC I need to break the recursion when I find the Self property
// otherwise it will be an infinite recursion
Console.WriteLine($"Found Self! {obj.GetType()}");
}
else
{
DumpObject(value, nestingLevel + 1);
}
}
}
}
bool HasBaseType(Type type, string baseTypeName)
{
if (type == null) return false;
string typeName = type.Name;
if (baseTypeName == typeName) return true;
return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
}
bool ImplementsDictionary(Type t)
{
return t is IDictionary;
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f360277%2fwhat-is-the-best-way-to-dump-entire-objects-to-a-log-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
12 Answers
12
active
oldest
votes
12 Answers
12
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could base something on the ObjectDumper code that ships with the Linq samples.
Have also a look at the answer of this related question to get a sample.
Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
– Dan Esparza
Dec 11 '08 at 18:24
Doesn't seem to work for XmlDocuments...
– John Hunter
Jul 2 '09 at 13:42
4
It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
– Konrad Morawski
Sep 20 '12 at 6:57
3
nuget package for ObjectDumper is now available. It also provides an extension methodDumpToString
andDump
toObject
class. Handy.
– IsmailS
Jun 17 '15 at 9:43
1
w3wp.exe
crashes when I attempt to useObjectDumper
likeRequest.DumpToString("aaa");
– Paul
May 2 '16 at 15:39
add a comment |
You could base something on the ObjectDumper code that ships with the Linq samples.
Have also a look at the answer of this related question to get a sample.
Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
– Dan Esparza
Dec 11 '08 at 18:24
Doesn't seem to work for XmlDocuments...
– John Hunter
Jul 2 '09 at 13:42
4
It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
– Konrad Morawski
Sep 20 '12 at 6:57
3
nuget package for ObjectDumper is now available. It also provides an extension methodDumpToString
andDump
toObject
class. Handy.
– IsmailS
Jun 17 '15 at 9:43
1
w3wp.exe
crashes when I attempt to useObjectDumper
likeRequest.DumpToString("aaa");
– Paul
May 2 '16 at 15:39
add a comment |
You could base something on the ObjectDumper code that ships with the Linq samples.
Have also a look at the answer of this related question to get a sample.
You could base something on the ObjectDumper code that ships with the Linq samples.
Have also a look at the answer of this related question to get a sample.
edited May 23 '17 at 12:26
Community♦
11
11
answered Dec 11 '08 at 18:07
Mike Scott
8,74653547
8,74653547
Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
– Dan Esparza
Dec 11 '08 at 18:24
Doesn't seem to work for XmlDocuments...
– John Hunter
Jul 2 '09 at 13:42
4
It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
– Konrad Morawski
Sep 20 '12 at 6:57
3
nuget package for ObjectDumper is now available. It also provides an extension methodDumpToString
andDump
toObject
class. Handy.
– IsmailS
Jun 17 '15 at 9:43
1
w3wp.exe
crashes when I attempt to useObjectDumper
likeRequest.DumpToString("aaa");
– Paul
May 2 '16 at 15:39
add a comment |
Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
– Dan Esparza
Dec 11 '08 at 18:24
Doesn't seem to work for XmlDocuments...
– John Hunter
Jul 2 '09 at 13:42
4
It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
– Konrad Morawski
Sep 20 '12 at 6:57
3
nuget package for ObjectDumper is now available. It also provides an extension methodDumpToString
andDump
toObject
class. Handy.
– IsmailS
Jun 17 '15 at 9:43
1
w3wp.exe
crashes when I attempt to useObjectDumper
likeRequest.DumpToString("aaa");
– Paul
May 2 '16 at 15:39
Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
– Dan Esparza
Dec 11 '08 at 18:24
Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
– Dan Esparza
Dec 11 '08 at 18:24
Doesn't seem to work for XmlDocuments...
– John Hunter
Jul 2 '09 at 13:42
Doesn't seem to work for XmlDocuments...
– John Hunter
Jul 2 '09 at 13:42
4
4
It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
– Konrad Morawski
Sep 20 '12 at 6:57
It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
– Konrad Morawski
Sep 20 '12 at 6:57
3
3
nuget package for ObjectDumper is now available. It also provides an extension method
DumpToString
and Dump
to Object
class. Handy.– IsmailS
Jun 17 '15 at 9:43
nuget package for ObjectDumper is now available. It also provides an extension method
DumpToString
and Dump
to Object
class. Handy.– IsmailS
Jun 17 '15 at 9:43
1
1
w3wp.exe
crashes when I attempt to use ObjectDumper
like Request.DumpToString("aaa");
– Paul
May 2 '16 at 15:39
w3wp.exe
crashes when I attempt to use ObjectDumper
like Request.DumpToString("aaa");
– Paul
May 2 '16 at 15:39
add a comment |
For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).
using Newtonsoft.Json;
public static class F
{
public static string Dump(object obj)
{
return JsonConvert.SerializeObject(obj);
}
}
Then in your Immediate Window
,
var lookHere = F.Dump(myobj);
lookHere will auto-show up in the Locals
window prepended with a $ or you can add a watch to it. On the right hand side of the Value
column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.
I am using Visual Studio 2013.
2
SerializeObj -> SerializeObject?
– Wiseman
Oct 27 '14 at 12:07
Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
– Восилей
Apr 23 at 17:45
add a comment |
For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).
using Newtonsoft.Json;
public static class F
{
public static string Dump(object obj)
{
return JsonConvert.SerializeObject(obj);
}
}
Then in your Immediate Window
,
var lookHere = F.Dump(myobj);
lookHere will auto-show up in the Locals
window prepended with a $ or you can add a watch to it. On the right hand side of the Value
column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.
I am using Visual Studio 2013.
2
SerializeObj -> SerializeObject?
– Wiseman
Oct 27 '14 at 12:07
Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
– Восилей
Apr 23 at 17:45
add a comment |
For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).
using Newtonsoft.Json;
public static class F
{
public static string Dump(object obj)
{
return JsonConvert.SerializeObject(obj);
}
}
Then in your Immediate Window
,
var lookHere = F.Dump(myobj);
lookHere will auto-show up in the Locals
window prepended with a $ or you can add a watch to it. On the right hand side of the Value
column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.
I am using Visual Studio 2013.
For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).
using Newtonsoft.Json;
public static class F
{
public static string Dump(object obj)
{
return JsonConvert.SerializeObject(obj);
}
}
Then in your Immediate Window
,
var lookHere = F.Dump(myobj);
lookHere will auto-show up in the Locals
window prepended with a $ or you can add a watch to it. On the right hand side of the Value
column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.
I am using Visual Studio 2013.
edited Oct 27 '14 at 21:32
answered Oct 3 '14 at 15:14
Jason
3,5802437
3,5802437
2
SerializeObj -> SerializeObject?
– Wiseman
Oct 27 '14 at 12:07
Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
– Восилей
Apr 23 at 17:45
add a comment |
2
SerializeObj -> SerializeObject?
– Wiseman
Oct 27 '14 at 12:07
Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
– Восилей
Apr 23 at 17:45
2
2
SerializeObj -> SerializeObject?
– Wiseman
Oct 27 '14 at 12:07
SerializeObj -> SerializeObject?
– Wiseman
Oct 27 '14 at 12:07
Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
– Восилей
Apr 23 at 17:45
Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
– Восилей
Apr 23 at 17:45
add a comment |
I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:
private string ObjectToXml(object output)
{
string objectAsXmlString;
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
try
{
xs.Serialize(sw, output);
objectAsXmlString = sw.ToString();
}
catch (Exception ex)
{
objectAsXmlString = ex.ToString();
}
}
return objectAsXmlString;
}
You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.
2
In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
– Nikita G.
Nov 10 '13 at 9:14
I keep getting from this:Failed to access type 'System.__ComObject' failed
. Noob to c#, would appreciate help.
– GuySoft
Oct 18 '14 at 18:50
1
@GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
– Bernhard Hofmann
Oct 20 '14 at 9:15
@BernhardHofmann Thanks will look in to it
– GuySoft
Oct 20 '14 at 12:35
@BernhardHofmann Yes, seems that way :-/
– GuySoft
Oct 23 '14 at 13:31
|
show 1 more comment
I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:
private string ObjectToXml(object output)
{
string objectAsXmlString;
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
try
{
xs.Serialize(sw, output);
objectAsXmlString = sw.ToString();
}
catch (Exception ex)
{
objectAsXmlString = ex.ToString();
}
}
return objectAsXmlString;
}
You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.
2
In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
– Nikita G.
Nov 10 '13 at 9:14
I keep getting from this:Failed to access type 'System.__ComObject' failed
. Noob to c#, would appreciate help.
– GuySoft
Oct 18 '14 at 18:50
1
@GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
– Bernhard Hofmann
Oct 20 '14 at 9:15
@BernhardHofmann Thanks will look in to it
– GuySoft
Oct 20 '14 at 12:35
@BernhardHofmann Yes, seems that way :-/
– GuySoft
Oct 23 '14 at 13:31
|
show 1 more comment
I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:
private string ObjectToXml(object output)
{
string objectAsXmlString;
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
try
{
xs.Serialize(sw, output);
objectAsXmlString = sw.ToString();
}
catch (Exception ex)
{
objectAsXmlString = ex.ToString();
}
}
return objectAsXmlString;
}
You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.
I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:
private string ObjectToXml(object output)
{
string objectAsXmlString;
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
try
{
xs.Serialize(sw, output);
objectAsXmlString = sw.ToString();
}
catch (Exception ex)
{
objectAsXmlString = ex.ToString();
}
}
return objectAsXmlString;
}
You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.
answered Dec 11 '08 at 18:08
Bernhard Hofmann
6,917115277
6,917115277
2
In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
– Nikita G.
Nov 10 '13 at 9:14
I keep getting from this:Failed to access type 'System.__ComObject' failed
. Noob to c#, would appreciate help.
– GuySoft
Oct 18 '14 at 18:50
1
@GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
– Bernhard Hofmann
Oct 20 '14 at 9:15
@BernhardHofmann Thanks will look in to it
– GuySoft
Oct 20 '14 at 12:35
@BernhardHofmann Yes, seems that way :-/
– GuySoft
Oct 23 '14 at 13:31
|
show 1 more comment
2
In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
– Nikita G.
Nov 10 '13 at 9:14
I keep getting from this:Failed to access type 'System.__ComObject' failed
. Noob to c#, would appreciate help.
– GuySoft
Oct 18 '14 at 18:50
1
@GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
– Bernhard Hofmann
Oct 20 '14 at 9:15
@BernhardHofmann Thanks will look in to it
– GuySoft
Oct 20 '14 at 12:35
@BernhardHofmann Yes, seems that way :-/
– GuySoft
Oct 23 '14 at 13:31
2
2
In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
– Nikita G.
Nov 10 '13 at 9:14
In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
– Nikita G.
Nov 10 '13 at 9:14
I keep getting from this:
Failed to access type 'System.__ComObject' failed
. Noob to c#, would appreciate help.– GuySoft
Oct 18 '14 at 18:50
I keep getting from this:
Failed to access type 'System.__ComObject' failed
. Noob to c#, would appreciate help.– GuySoft
Oct 18 '14 at 18:50
1
1
@GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
– Bernhard Hofmann
Oct 20 '14 at 9:15
@GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
– Bernhard Hofmann
Oct 20 '14 at 9:15
@BernhardHofmann Thanks will look in to it
– GuySoft
Oct 20 '14 at 12:35
@BernhardHofmann Thanks will look in to it
– GuySoft
Oct 20 '14 at 12:35
@BernhardHofmann Yes, seems that way :-/
– GuySoft
Oct 23 '14 at 13:31
@BernhardHofmann Yes, seems that way :-/
– GuySoft
Oct 23 '14 at 13:31
|
show 1 more comment
I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.
Example usage:
var model = new TestModel();
Console.WriteLine(model.Dump());
and output:
{
Int: 1,
String: One,
DateTime: 2010-04-11,
Guid: c050437f6fcd46be9b2d0806a0860b3e,
EmptyIntList: ,
IntList:
[
1,
2,
3
],
StringList:
[
one,
two,
three
],
StringIntMap:
{
a: 1,
b: 2,
c: 3
}
}
1
It doesn't work for fields. The OP was explicitly asking about "entire objects".
– Konrad Morawski
Sep 20 '12 at 7:04
4
He didn't say fields
- he saidentire objects
, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple? objectname
will give me a nicely formatted 'dump' of the object").? objectname
prints out all the fields as well.This has been immensely helpful - one of my most used extension methods to date
- I'm not questioning that it's useful, only that it dumps entire objects.
– Konrad Morawski
Sep 20 '12 at 8:24
2
@KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
– mythz
Sep 20 '12 at 9:08
1
@mythz yes of course you need to prevent a stack overflow (eg. everyInt32
field has aMaxValue
field, which is anInt32
itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one),? objectname
in theImmediate Window
does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
– Konrad Morawski
Sep 20 '12 at 9:33
2
-1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
– user565869
Jul 14 '14 at 19:26
|
show 2 more comments
I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.
Example usage:
var model = new TestModel();
Console.WriteLine(model.Dump());
and output:
{
Int: 1,
String: One,
DateTime: 2010-04-11,
Guid: c050437f6fcd46be9b2d0806a0860b3e,
EmptyIntList: ,
IntList:
[
1,
2,
3
],
StringList:
[
one,
two,
three
],
StringIntMap:
{
a: 1,
b: 2,
c: 3
}
}
1
It doesn't work for fields. The OP was explicitly asking about "entire objects".
– Konrad Morawski
Sep 20 '12 at 7:04
4
He didn't say fields
- he saidentire objects
, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple? objectname
will give me a nicely formatted 'dump' of the object").? objectname
prints out all the fields as well.This has been immensely helpful - one of my most used extension methods to date
- I'm not questioning that it's useful, only that it dumps entire objects.
– Konrad Morawski
Sep 20 '12 at 8:24
2
@KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
– mythz
Sep 20 '12 at 9:08
1
@mythz yes of course you need to prevent a stack overflow (eg. everyInt32
field has aMaxValue
field, which is anInt32
itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one),? objectname
in theImmediate Window
does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
– Konrad Morawski
Sep 20 '12 at 9:33
2
-1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
– user565869
Jul 14 '14 at 19:26
|
show 2 more comments
I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.
Example usage:
var model = new TestModel();
Console.WriteLine(model.Dump());
and output:
{
Int: 1,
String: One,
DateTime: 2010-04-11,
Guid: c050437f6fcd46be9b2d0806a0860b3e,
EmptyIntList: ,
IntList:
[
1,
2,
3
],
StringList:
[
one,
two,
three
],
StringIntMap:
{
a: 1,
b: 2,
c: 3
}
}
I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.
Example usage:
var model = new TestModel();
Console.WriteLine(model.Dump());
and output:
{
Int: 1,
String: One,
DateTime: 2010-04-11,
Guid: c050437f6fcd46be9b2d0806a0860b3e,
EmptyIntList: ,
IntList:
[
1,
2,
3
],
StringList:
[
one,
two,
three
],
StringIntMap:
{
a: 1,
b: 2,
c: 3
}
}
edited May 17 '11 at 15:00
answered Aug 18 '10 at 16:04
mythz
117k14193333
117k14193333
1
It doesn't work for fields. The OP was explicitly asking about "entire objects".
– Konrad Morawski
Sep 20 '12 at 7:04
4
He didn't say fields
- he saidentire objects
, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple? objectname
will give me a nicely formatted 'dump' of the object").? objectname
prints out all the fields as well.This has been immensely helpful - one of my most used extension methods to date
- I'm not questioning that it's useful, only that it dumps entire objects.
– Konrad Morawski
Sep 20 '12 at 8:24
2
@KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
– mythz
Sep 20 '12 at 9:08
1
@mythz yes of course you need to prevent a stack overflow (eg. everyInt32
field has aMaxValue
field, which is anInt32
itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one),? objectname
in theImmediate Window
does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
– Konrad Morawski
Sep 20 '12 at 9:33
2
-1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
– user565869
Jul 14 '14 at 19:26
|
show 2 more comments
1
It doesn't work for fields. The OP was explicitly asking about "entire objects".
– Konrad Morawski
Sep 20 '12 at 7:04
4
He didn't say fields
- he saidentire objects
, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple? objectname
will give me a nicely formatted 'dump' of the object").? objectname
prints out all the fields as well.This has been immensely helpful - one of my most used extension methods to date
- I'm not questioning that it's useful, only that it dumps entire objects.
– Konrad Morawski
Sep 20 '12 at 8:24
2
@KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
– mythz
Sep 20 '12 at 9:08
1
@mythz yes of course you need to prevent a stack overflow (eg. everyInt32
field has aMaxValue
field, which is anInt32
itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one),? objectname
in theImmediate Window
does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
– Konrad Morawski
Sep 20 '12 at 9:33
2
-1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
– user565869
Jul 14 '14 at 19:26
1
1
It doesn't work for fields. The OP was explicitly asking about "entire objects".
– Konrad Morawski
Sep 20 '12 at 7:04
It doesn't work for fields. The OP was explicitly asking about "entire objects".
– Konrad Morawski
Sep 20 '12 at 7:04
4
4
He didn't say fields
- he said entire objects
, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname
will give me a nicely formatted 'dump' of the object"). ? objectname
prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date
- I'm not questioning that it's useful, only that it dumps entire objects.– Konrad Morawski
Sep 20 '12 at 8:24
He didn't say fields
- he said entire objects
, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname
will give me a nicely formatted 'dump' of the object"). ? objectname
prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date
- I'm not questioning that it's useful, only that it dumps entire objects.– Konrad Morawski
Sep 20 '12 at 8:24
2
2
@KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
– mythz
Sep 20 '12 at 9:08
@KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
– mythz
Sep 20 '12 at 9:08
1
1
@mythz yes of course you need to prevent a stack overflow (eg. every
Int32
field has a MaxValue
field, which is an Int32
itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname
in the Immediate Window
does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.– Konrad Morawski
Sep 20 '12 at 9:33
@mythz yes of course you need to prevent a stack overflow (eg. every
Int32
field has a MaxValue
field, which is an Int32
itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname
in the Immediate Window
does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.– Konrad Morawski
Sep 20 '12 at 9:33
2
2
-1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
– user565869
Jul 14 '14 at 19:26
-1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
– user565869
Jul 14 '14 at 19:26
|
show 2 more comments
You could use Visual Studio Immediate Window
Just paste this (change actual
to your object name obviously):
Newtonsoft.Json.JsonConvert.SerializeObject(actual);
It should print object in JSON
You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes ("
) with "
and newlines (rn
) with empty space, then remove double quotes ("
) from beginning and end and paste it to jsbeautifier to make it more readable.
UPDATE to OP's comment
public static class Dumper
{
public static void Dump(this object obj)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
}
}
this should allow you to dump any object.
Hope this saves you some time.
Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
– Dan Esparza
Jun 23 '15 at 15:38
@DanEsparzaConsole.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual));
? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
– Matas Vaitkevicius
Jun 23 '15 at 15:52
1
FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
– Walter
Aug 31 '16 at 1:00
add a comment |
You could use Visual Studio Immediate Window
Just paste this (change actual
to your object name obviously):
Newtonsoft.Json.JsonConvert.SerializeObject(actual);
It should print object in JSON
You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes ("
) with "
and newlines (rn
) with empty space, then remove double quotes ("
) from beginning and end and paste it to jsbeautifier to make it more readable.
UPDATE to OP's comment
public static class Dumper
{
public static void Dump(this object obj)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
}
}
this should allow you to dump any object.
Hope this saves you some time.
Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
– Dan Esparza
Jun 23 '15 at 15:38
@DanEsparzaConsole.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual));
? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
– Matas Vaitkevicius
Jun 23 '15 at 15:52
1
FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
– Walter
Aug 31 '16 at 1:00
add a comment |
You could use Visual Studio Immediate Window
Just paste this (change actual
to your object name obviously):
Newtonsoft.Json.JsonConvert.SerializeObject(actual);
It should print object in JSON
You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes ("
) with "
and newlines (rn
) with empty space, then remove double quotes ("
) from beginning and end and paste it to jsbeautifier to make it more readable.
UPDATE to OP's comment
public static class Dumper
{
public static void Dump(this object obj)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
}
}
this should allow you to dump any object.
Hope this saves you some time.
You could use Visual Studio Immediate Window
Just paste this (change actual
to your object name obviously):
Newtonsoft.Json.JsonConvert.SerializeObject(actual);
It should print object in JSON
You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes ("
) with "
and newlines (rn
) with empty space, then remove double quotes ("
) from beginning and end and paste it to jsbeautifier to make it more readable.
UPDATE to OP's comment
public static class Dumper
{
public static void Dump(this object obj)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
}
}
this should allow you to dump any object.
Hope this saves you some time.
edited Jun 23 '15 at 16:05
answered Jun 23 '15 at 10:01
Matas Vaitkevicius
32.4k15161172
32.4k15161172
Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
– Dan Esparza
Jun 23 '15 at 15:38
@DanEsparzaConsole.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual));
? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
– Matas Vaitkevicius
Jun 23 '15 at 15:52
1
FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
– Walter
Aug 31 '16 at 1:00
add a comment |
Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
– Dan Esparza
Jun 23 '15 at 15:38
@DanEsparzaConsole.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual));
? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
– Matas Vaitkevicius
Jun 23 '15 at 15:52
1
FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
– Walter
Aug 31 '16 at 1:00
Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
– Dan Esparza
Jun 23 '15 at 15:38
Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
– Dan Esparza
Jun 23 '15 at 15:38
@DanEsparza
Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual));
? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…– Matas Vaitkevicius
Jun 23 '15 at 15:52
@DanEsparza
Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual));
? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…– Matas Vaitkevicius
Jun 23 '15 at 15:52
1
1
FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
– Walter
Aug 31 '16 at 1:00
FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
– Walter
Aug 31 '16 at 1:00
add a comment |
Here is a stupidly simple way to write a flat object, nicely formatted:
using Newtonsoft.Json.Linq;
Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());
What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject
, and then converted to JSON string by ToString
. (And of course a JSON string is a very nice representation of a simple object, especially since ToString
will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using +
to concat a string and an object), but I kinda like to specify it here.
3
JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
– Tertium
Aug 23 '16 at 23:04
add a comment |
Here is a stupidly simple way to write a flat object, nicely formatted:
using Newtonsoft.Json.Linq;
Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());
What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject
, and then converted to JSON string by ToString
. (And of course a JSON string is a very nice representation of a simple object, especially since ToString
will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using +
to concat a string and an object), but I kinda like to specify it here.
3
JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
– Tertium
Aug 23 '16 at 23:04
add a comment |
Here is a stupidly simple way to write a flat object, nicely formatted:
using Newtonsoft.Json.Linq;
Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());
What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject
, and then converted to JSON string by ToString
. (And of course a JSON string is a very nice representation of a simple object, especially since ToString
will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using +
to concat a string and an object), but I kinda like to specify it here.
Here is a stupidly simple way to write a flat object, nicely formatted:
using Newtonsoft.Json.Linq;
Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());
What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject
, and then converted to JSON string by ToString
. (And of course a JSON string is a very nice representation of a simple object, especially since ToString
will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using +
to concat a string and an object), but I kinda like to specify it here.
answered Jun 10 '14 at 21:08
Hot Licks
37.7k1577133
37.7k1577133
3
JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
– Tertium
Aug 23 '16 at 23:04
add a comment |
3
JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
– Tertium
Aug 23 '16 at 23:04
3
3
JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
– Tertium
Aug 23 '16 at 23:04
JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
– Tertium
Aug 23 '16 at 23:04
add a comment |
You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):
MyObject
Property1 = value
Property2 = value2
OtherObject
OtherProperty = value ...
add a comment |
You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):
MyObject
Property1 = value
Property2 = value2
OtherObject
OtherProperty = value ...
add a comment |
You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):
MyObject
Property1 = value
Property2 = value2
OtherObject
OtherProperty = value ...
You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):
MyObject
Property1 = value
Property2 = value2
OtherObject
OtherProperty = value ...
answered Dec 11 '08 at 18:05
Ricardo Villamil
4,36612625
4,36612625
add a comment |
add a comment |
What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.
add a comment |
What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.
add a comment |
What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.
What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.
answered Dec 11 '08 at 19:05
Darryl Braaten
4,28433145
4,28433145
add a comment |
add a comment |
I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.
add a comment |
I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.
add a comment |
I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.
I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.
answered Aug 25 '15 at 12:06
Marek Dzikiewicz
2,52911619
2,52911619
add a comment |
add a comment |
Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel = 0)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().IsPrimitive)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
bool ImplementsDictionary(Type t)
{
return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
}
}
1
this will die horribly if you have aDate
property in your inner object ... just saying ...
– Noctis
Sep 7 '17 at 4:43
add a comment |
Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel = 0)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().IsPrimitive)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
bool ImplementsDictionary(Type t)
{
return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
}
}
1
this will die horribly if you have aDate
property in your inner object ... just saying ...
– Noctis
Sep 7 '17 at 4:43
add a comment |
Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel = 0)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().IsPrimitive)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
bool ImplementsDictionary(Type t)
{
return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
}
}
Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel = 0)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().IsPrimitive)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
bool ImplementsDictionary(Type t)
{
return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
}
}
edited Feb 21 '17 at 2:40
answered Feb 16 '17 at 3:02
engineforce
1,1691112
1,1691112
1
this will die horribly if you have aDate
property in your inner object ... just saying ...
– Noctis
Sep 7 '17 at 4:43
add a comment |
1
this will die horribly if you have aDate
property in your inner object ... just saying ...
– Noctis
Sep 7 '17 at 4:43
1
1
this will die horribly if you have a
Date
property in your inner object ... just saying ...– Noctis
Sep 7 '17 at 4:43
this will die horribly if you have a
Date
property in your inner object ... just saying ...– Noctis
Sep 7 '17 at 4:43
add a comment |
You can write your own WriteLine method-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
Use it like-
WriteLine(myObject);
To write a collection we can use-
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
The method may look like-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
else if (t.GetProperties().Any())
{
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
}
Using if, else if
and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.
Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
– Dan Esparza
Mar 1 '16 at 14:50
@DanEsparza Thanks to show me the way to be more specific.
– Ariful Islam
Mar 2 '16 at 6:33
add a comment |
You can write your own WriteLine method-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
Use it like-
WriteLine(myObject);
To write a collection we can use-
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
The method may look like-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
else if (t.GetProperties().Any())
{
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
}
Using if, else if
and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.
Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
– Dan Esparza
Mar 1 '16 at 14:50
@DanEsparza Thanks to show me the way to be more specific.
– Ariful Islam
Mar 2 '16 at 6:33
add a comment |
You can write your own WriteLine method-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
Use it like-
WriteLine(myObject);
To write a collection we can use-
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
The method may look like-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
else if (t.GetProperties().Any())
{
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
}
Using if, else if
and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.
You can write your own WriteLine method-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
Use it like-
WriteLine(myObject);
To write a collection we can use-
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
The method may look like-
public static void WriteLine<T>(T obj)
{
var t = typeof(T);
var ifaces = t.GetInterfaces();
if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
{
dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
while (lst.MoveNext())
{
WriteLine(lst.Current);
}
}
else if (t.GetProperties().Any())
{
var props = t.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
}
Using if, else if
and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.
edited Mar 2 '16 at 6:28
answered Feb 26 '16 at 17:45
Ariful Islam
36737
36737
Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
– Dan Esparza
Mar 1 '16 at 14:50
@DanEsparza Thanks to show me the way to be more specific.
– Ariful Islam
Mar 2 '16 at 6:33
add a comment |
Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
– Dan Esparza
Mar 1 '16 at 14:50
@DanEsparza Thanks to show me the way to be more specific.
– Ariful Islam
Mar 2 '16 at 6:33
Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
– Dan Esparza
Mar 1 '16 at 14:50
Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
– Dan Esparza
Mar 1 '16 at 14:50
@DanEsparza Thanks to show me the way to be more specific.
– Ariful Islam
Mar 2 '16 at 6:33
@DanEsparza Thanks to show me the way to be more specific.
– Ariful Islam
Mar 2 '16 at 6:33
add a comment |
Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:
/// <summary>
/// Based on: https://stackoverflow.com/a/42264037/6155481
/// </summary>
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
// TODO: Prevent recursion due to circular reference
if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
{
// In ObjC I need to break the recursion when I find the Self property
// otherwise it will be an infinite recursion
Console.WriteLine($"Found Self! {obj.GetType()}");
}
else
{
DumpObject(value, nestingLevel + 1);
}
}
}
}
bool HasBaseType(Type type, string baseTypeName)
{
if (type == null) return false;
string typeName = type.Name;
if (baseTypeName == typeName) return true;
return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
}
bool ImplementsDictionary(Type t)
{
return t is IDictionary;
}
}
add a comment |
Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:
/// <summary>
/// Based on: https://stackoverflow.com/a/42264037/6155481
/// </summary>
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
// TODO: Prevent recursion due to circular reference
if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
{
// In ObjC I need to break the recursion when I find the Self property
// otherwise it will be an infinite recursion
Console.WriteLine($"Found Self! {obj.GetType()}");
}
else
{
DumpObject(value, nestingLevel + 1);
}
}
}
}
bool HasBaseType(Type type, string baseTypeName)
{
if (type == null) return false;
string typeName = type.Name;
if (baseTypeName == typeName) return true;
return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
}
bool ImplementsDictionary(Type t)
{
return t is IDictionary;
}
}
add a comment |
Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:
/// <summary>
/// Based on: https://stackoverflow.com/a/42264037/6155481
/// </summary>
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
// TODO: Prevent recursion due to circular reference
if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
{
// In ObjC I need to break the recursion when I find the Self property
// otherwise it will be an infinite recursion
Console.WriteLine($"Found Self! {obj.GetType()}");
}
else
{
DumpObject(value, nestingLevel + 1);
}
}
}
}
bool HasBaseType(Type type, string baseTypeName)
{
if (type == null) return false;
string typeName = type.Name;
if (baseTypeName == typeName) return true;
return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
}
bool ImplementsDictionary(Type t)
{
return t is IDictionary;
}
}
Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:
/// <summary>
/// Based on: https://stackoverflow.com/a/42264037/6155481
/// </summary>
public class ObjectDumper
{
public static string Dump(object obj)
{
return new ObjectDumper().DumpObject(obj);
}
StringBuilder _dumpBuilder = new StringBuilder();
string DumpObject(object obj)
{
DumpObject(obj, 0);
return _dumpBuilder.ToString();
}
void DumpObject(object obj, int nestingLevel)
{
var nestingSpaces = "".PadLeft(nestingLevel * 4);
if (obj == null)
{
_dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
}
else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
{
_dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
}
else if (ImplementsDictionary(obj.GetType()))
{
using (var e = ((dynamic)obj).GetEnumerator())
{
var enumerator = (IEnumerator)e;
while (enumerator.MoveNext())
{
dynamic p = enumerator.Current;
var key = p.Key;
var value = p.Value;
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
DumpObject(value, nestingLevel + 1);
}
}
}
else if (obj is IEnumerable)
{
foreach (dynamic p in obj as IEnumerable)
{
DumpObject(p, nestingLevel);
}
}
else
{
foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
_dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
// TODO: Prevent recursion due to circular reference
if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
{
// In ObjC I need to break the recursion when I find the Self property
// otherwise it will be an infinite recursion
Console.WriteLine($"Found Self! {obj.GetType()}");
}
else
{
DumpObject(value, nestingLevel + 1);
}
}
}
}
bool HasBaseType(Type type, string baseTypeName)
{
if (type == null) return false;
string typeName = type.Name;
if (baseTypeName == typeName) return true;
return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
}
bool ImplementsDictionary(Type t)
{
return t is IDictionary;
}
}
answered Nov 11 at 22:09
gianlucaparadise
7518
7518
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f360277%2fwhat-is-the-best-way-to-dump-entire-objects-to-a-log-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23
This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20