如何在LinqPad中转储()一个Newtonsoft JObject?

Ken*_*son 19 c# json json.net linqpad

在LinqPad中,尝试调用.Dump()Newtonsoft JSON.Net会JObject产生异常:

RuntimeBinderException:'Newtonsoft.Json.Linq.JObject'不包含'转储'的定义.

这适用于LinqPad中的几乎所有其他内容.我想找出一种方法,它会JObject像其他对象一样转储出一个Newtonsoft ,显示属性名称,值等.

我已经想出如何让它转储JSON字符串,但我想看到一个对象得到输出而不仅仅是一个文本字符串.

rda*_*sau 26

对于那些想要从JSON字符串获得漂亮的LINQPad输出的人来说,反序列化ExpandoObject是一种有效的方法,并且可以递归地在数据中的任何层次结构中运行:

JsonConvert.DeserializeObject<ExpandoObject>(myJSONString).Dump();

扩展它以涵盖实际问题,JObject上的这些行的扩展方法可以解决这个问题:

public static class ExtMethods
{
    public static JObject DumpPretty(this JObject jo)
    {
        var jsonString = JsonConvert.SerializeObject(jo);
        JsonConvert.DeserializeObject<ExpandoObject>(jsonString).Dump();

        return jo;  // return input in the spirit of LINQPad's Dump() method.
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是最有效的方法,但是为了在LINQPad中挖掘时快速使用它可以解决问题.

  • ps,你可以使用`jo.ToObject <ExpandoObject>()`而不是序列化/反序列化. (7认同)

D S*_*ley 15

它是一个静态扩展方法,因此您可以将其称为静态方法:

LINQPad.Extensions.Dump(jObject);
Run Code Online (Sandbox Code Playgroud)

我看到在某些类型上发生这种情况(我猜)编译器由于某种原因无法绑定到扩展名.

一个帖子上LinqPad的网站和博客中使用关于Dump()dynamic对象.

您可以尝试创建另一个Dump()扩展,该扩展检查可以巧妙地编辑的属性JObject并创建一个Dictionary .Dump

这样的事情:(根据JObject的定义完成WAG):

var values = jObject.Properties.ToDictionary(p=>p.Name, p=>p.Value);
values.Dump();
Run Code Online (Sandbox Code Playgroud)

当然你可以为嵌套对象添加递归等:

//Usage: GetProperties(jObject).Dump();
public static object GetProperties(object o)
{
    JObject j = o as JObject;
    if(j == null)
    {
        return o.ToString();
    }
    return j.Properties().ToDictionary(p=>p.Name,p=>GetProperties(p.Value));
}
Run Code Online (Sandbox Code Playgroud)

  • 博客文章特定于`ExpandoObject`以及它实现`IDictionary <string,object>`的方式,我相信.它可能*当`JObject`实现`IDictionary <string,JToken>`它会给出一个很好的输出,但它不是*一般*动态对象处理. (2认同)

Jon*_*eet 5

我的猜测是你正在做这样的事情:

dynamic foo = ...;
foo.Dump();
Run Code Online (Sandbox Code Playgroud)

扩展方法(即Dump)不适用于动态类型.如果您使用:

object foo = ...;
foo.Dump();
Run Code Online (Sandbox Code Playgroud)

然后我预计它会"正常"工作.它可能不会做你真正想要的 - 因为属性on JObject不是动态提供的JSON属性.

(根据D Stanley的答案明确地调用扩展方法也会起作用,但你可能会发现它仍然作为扩展方法更方便.)

编辑:我强烈怀疑,Dump根本不会给你你想要的东西,因为它对Json.NET一无所知,并且可能不会像(比如说)调试器那样处理动态对象.您可能最好编写自己的Dump方法来迭代它的属性JObject并递归地转储它们.如果你仍然希望找到开箱即用的东西,你可能应该查看Json.NET文档,而不是寻找LINQPad,虽然我不知道你是否会发现任何东西.

  • @KenMason:那就是调用LINQPad`Dump`方法.这是我的回答,说它可能不会做你想要的......它使用对象的*actual*属性,而不是动态的属性.我怀疑你可能找不到任何完全按照你想要的方式 - 至少不是开箱即用.我和D Stanley的答案虽然(IMO)对你如何使用"转储"的实际问题是合理的......但它只是"转储"没有做你想要的. (3认同)