解析JSON、扩展Fiddler

按文章结构,这部分应该给出WCFRest项目示例,我想WinForm示例足够详尽了,况且WCFRest还不需要使用插件AppDomain那一套,于是把最近写的Fiddler扩展搬上来吧。

Fiddler有一套自成的插件系统,可以在其官方网站找到完整文档(戳这里)。通过其提供的一整套接口,我们可以从界面至功能全方位扩展它。这里主题简单,我们只为其添加一个JSON解析界面。

PART I:JSON解析

Mgen有一个JSON解析范例(戳这里)代码相当好看,WPF模块绑定也很强大。这里使用Json.com的一个示例稍作修改,解析效果如下:

上述代码过于忠实地体现了Newtonsoft的设计,只有JValue被解析成叶节点,其他JToken对象全部是枝节点,解析出来的JSON树层次太深可读性不够好。

Newtonsoft中JSON结构:

这里重新设计结构图如下:

一共有4种节点:指示值的JsonValueNode叶节点、指示键值对的JsonPropertyNode的叶节点,指示数组的JsonArrayNode枝节点,及指示对象的JsonObjectNode的树节点。解析时关键在对JProperty的处理:把Value为JValue的JProperty对象解析成JsonPropertyNode叶节点,Value为JContainer的JProperty视子节点属性实例成JsonArrayNode或JsonObjectNode树节点,初步代码如下:

public class JsonNode
{
public IEnumerable<JsonNode> Children { get; internal set; } internal JsonNode()
{
}
} public class JsonValueNode : JsonNode
{
public Object Value { get; private set; } public JsonValueNode(Object value)
{
Value = value;
} public override String ToString()
{
return Value != null ? Value.ToString() : "<null>";
}
} public class JsonPropertyNode : JsonNode
{
public String Name { get; private set; }
public Object Value { get; private set; } public JsonPropertyNode(String name, Object value)
{
Name = name;
Value = value;
} public override String ToString()
{
return String.Concat(Name, " : ", (Value != null ? Value.ToString() : "<null>"));
}
} public class JsonArrayNode : JsonNode
{
public String Name { get; private set; } public JsonArrayNode(String name)
{
Name = name ?? "[]";
} public override String ToString()
{
return Name;
}
} public class JsonObjectNode : JsonNode
{
public String Name { get; private set; } public JsonObjectNode(String name)
{
Name = name ?? "{}";
} public override String ToString()
{
return Name;
}
}

JsonNodeFactory作为JsonNode的建造者:

public class JsonNodeFactory
{
public static JsonNode CreateFromJToken(JToken jtoken)
{
if (jtoken is JValue)
{
return new JsonValueNode(((JValue)jtoken).Value);
}
else if (jtoken is JProperty)
{
JProperty jproperty = (JProperty)jtoken;
if (jproperty.Value is JValue)
{
return new JsonPropertyNode(jproperty.Name, ((JValue)jproperty.Value).Value);
}
else if (jproperty.Value is JArray)
{
JsonArrayNode jsonNode = new JsonArrayNode(jproperty.Name);
jsonNode.Children = ((JArray)jproperty.Value).Children().Select(n => CreateFromJToken(n));
return jsonNode;
}
else if (jproperty.Value is JObject)
{
JsonObjectNode jsonNode = new JsonObjectNode(jproperty.Name);
jsonNode.Children = ((JObject)jproperty.Value).Children().Select(n => CreateFromJToken(n));
return jsonNode;
}
else
{
throw new Exception("Unknown JProperty");
}
}
else if (jtoken is JArray)
{
JsonArrayNode jsonNode = new JsonArrayNode(null);
jsonNode.Children = ((JArray)jtoken).Children().Select(n => CreateFromJToken(n));
return jsonNode;
}
else if (jtoken is JObject)
{
JsonObjectNode jsonNode = new JsonObjectNode(null);
jsonNode.Children = ((JObject)jtoken).Children().Select(n => CreateFromJToken(n));
return jsonNode;
}
else
{
throw new Exception("Unknown jtoken");
}
}
}

文章后面的代码文件中更具体的实现加入了父节点与索引,ToString()逻辑更完备。客户端调用:

class Program
{
static void Main(string[] args)
{
JToken jtoken = JToken.Parse(System.IO.File.ReadAllText("json.txt"));
JsonNode node = JsonNodeFactory.CreateFromJToken(jtoken);
Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
Display(node);
} private static void Display(JsonNode node)
{
Debug.WriteLine(node);
if (node.Children != null)
{
Debug.Indent();
foreach (JsonNode sub in node.Children)
{
Display(sub);
}
Debug.Unindent();
}
}
}

json.txt见截图与后文代码文件,新的解析结构:

PART2:Fiddler插件

Fiddler自带的JSON显示是一个简单的Tree,无法完成复杂功能。Codeplex上有一个JsonView项目(戳这里),Fiddler子项目丢到%Program Files%/Fiddler/Inspectors目录即可。问题在于它有BUG,且使用Newtonsoft的Json.Net版本极其低。没办法,重写一个。这里有2处需要注意:

1. 需要添加Public类,实现Inspector2、IResponseInspector2,抽象类Inspector2.AddToTab(TabPage o)是UI呈现方法,headers与body属性内部可以完成对自定义控件赋值;

2. 需要加入[assembly: Fiddler.RequiredVersion("x.x.x.x")]特性,位置不限。Fiddler目录有基于.Net Framework 2.0和4.0的版本,本例使用4.0,CLR版本兼容性、X64兼容性等具体内容请自行翻阅文档。

AddToTab方法大致内容如下:

public override void AddToTab(TabPage tabPage)
{
utrlJson = new UserControl_JsonView() { Dock = DockStyle.Fill };
tabPage.Text = "MyJson";
tabPage.Controls.Add(utrlJson);
}

这里使用了一个UserControl,暴露一个Content属性,内部使用TextBox和TreeView展示Json文本与JsonNode结构。

取消Fiddler引用及排除Plugin.cs,将项目类型设置为Windows应用程序,可以得到Form窗体程序;加入引用及Plugin.cs,将项目类型设置成类库,扔到%Program Files%/Fiddler/Inspectors目录便是Fiddler插件。这里加入了文本定位、节点分层展开、节点值复制(可以在TreeView上使用Ctrl+C进行智能复制)等方法,方便使用。

PART3:后记

感觉代码还是比较乱,JsonNode创建方法还可以提炼;水平所限,TextBox光标定位正则不够强大,需要优化;功能上讲,可以加入设置项以组织编码格式、Header解析、控件视图等。代码文件及二进制文件(戳这里)奉上。

解析JSON、扩展Fiddler的更多相关文章

  1. IIS支持解析json

      IIS支持解析json 一. windows XP   1. MIME设置: 在IIS的站点属性的HTTP头设置里,选MIME 映射中点击"文件类型"-"新类型&qu ...

  2. 更好更快更高效解析JSON说明

    现在来一个实例解析类,直接就把解析JSON到QVariant去了.唯一不足的是没有搞错误处理,具体方法也请各位自行参考json-c的发行文档,这样比较方便叙述,STL或者Boost我都没有认真接触过, ...

  3. UI进阶 解析XML 解析JSON

    1.数据解析 解析的基本概念 所谓“解析”:从事先规定好的格式中提取数据 解析的前提:提前约定好格式,数据提供方按照格式提供数据.数据获取方则按照格式获取数据 iOS开发常见的解析:XML解析.JSO ...

  4. jQuery解析JSON的问题

    在WEB数据传输过程中,json是以文本,即字符串的轻量级形式传递的,而客户端一般用JS操作的是接收到的JSON对象,所以,JSON对象和JSON字符串之间的相互转换.JSON数据的解析是关键. JS ...

  5. Json转model对象,model转json,解析json字符串

    GitHub链接: https://github.com/mozhenhau/D3Json D3Json 通过swift的反射特性,把json数据转换为model对象,本类最主要是解决了其他一般jso ...

  6. Android数据解析-JSON解析

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,基于JavaScript(Standard ECMA-262 3rd Edition - December ...

  7. Java解析json(二):jackson

    Java解析json(二):jackson   官方参考 Jackson Home Page:https://github.com/FasterXML/jackson Jackson Wiki:htt ...

  8. $Java-json系列(一):用GSON解析Json格式数据

    GSON是谷歌提供的开源库,用来解析Json格式的数据,非常好用.如果要使用GSON的话,则要先下载gson-2.2.4.jar这个文件,如果是在Android项目中使用,则在Android项目的li ...

  9. Gson+GsonFormat+Postman简单粗暴解析json

    现在有时候之前的项目需要返回来修改bug看到以下这段代码 if (test != null) { JSONTokener jsonParser = new JSONTokener(test); JSO ...

随机推荐

  1. Cassandra C++/NodeJs开发环境

    工作的需要,开始更多地倾向于去中心化的结构,目前看来Cassandra算是去中心化DB中性能/管理最热门的选择,崇尚其P2P的理念. 自身原因对JAVA不擅长(周围写C的好少),还是更热衷于C++/J ...

  2. POJ 3255 Roadblocks (次级短路问题)

    解决方案有许多美丽的地方.让我们跳回到到达终点跳回(例如有两点)....无论如何,这不是最短路,但它并不重要.算法能给出正确的结果 思考:而最短的路到同一点例程.spfa先正达恳求一次,求的最短路径的 ...

  3. RESTful API的设计原则

    好RESTful API的设计原则   说在前面,这篇文章是无意中发现的,因为感觉写的很好,所以翻译了一下.由于英文水平有限,难免有出错的地方,请看官理解一下.翻译和校正文章花了我大约2周的业余时间, ...

  4. 12个有趣的c面试题目

    1.gets()函数 问:请找出以下代码里的问题: #include<stdio.h>  int main(void)  {      char buff[10];      memset ...

  5. win7 wifi 无Internet訪问权限或者有限的訪问权限

    自己家的无线路由器,手机和笔记本都使用正常,可是一台新笔记本连上之后总是提示"有限的訪问权限",无法连公网. 网上的非常多办法都无论用,什么设置静态IP或者重新启动路由,基本都是瞎 ...

  6. 【COCOS2DX-游戏开发之三四】cocos2dx 3.0 TableView特殊使用方法:滚动时不能选择等等

    cocos2dx 3.0版本号TableView拍生自ScrollView,经常使用来做滚动列表,有几种特殊使用方法,不知道大家用到过没 要求:1.滚动时不能选中TableCell,非滚动状态才干选中 ...

  7. 使用SoapUI 测试Web Service

    原文:使用SoapUI 测试Web Service 如何测试写好的Webservice?你当然可以写代码来测试,但还是太麻烦,你得花时间去学习各语言的关于Webservice调用的相关API.这里推荐 ...

  8. Qt Creator(编译器MinGW)中使用__attribute__(packed)的问题

    http://www.bttr-software.de/forum/mix_entry.php?id=11767 假设我们从串口中读到一串数据,当我们想要处理这串数据的时候通常是这样做的: 1 将这些 ...

  9. at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)

    最近在做一个WinForm的项目. 使用vs2013开发. 数据库使用的是oracle. 在本地写了一个webservice .测试正常.发布到服务器的时候.就是提示了错误. 打开服务器上的日志.看到 ...

  10. android音乐播放器开发 SweetMusicPlayer 智能负载直插式歌词

    在一份书面的使用MediaPlayer播放音乐, http://blog.csdn.net/huweigoodboy/article/details/39862773.假设没有本地歌词怎么办?如今来将 ...