解析JSON、扩展Fiddler
解析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的更多相关文章
- IIS支持解析json
IIS支持解析json 一. windows XP 1. MIME设置: 在IIS的站点属性的HTTP头设置里,选MIME 映射中点击"文件类型"-"新类型&qu ...
- 更好更快更高效解析JSON说明
现在来一个实例解析类,直接就把解析JSON到QVariant去了.唯一不足的是没有搞错误处理,具体方法也请各位自行参考json-c的发行文档,这样比较方便叙述,STL或者Boost我都没有认真接触过, ...
- UI进阶 解析XML 解析JSON
1.数据解析 解析的基本概念 所谓“解析”:从事先规定好的格式中提取数据 解析的前提:提前约定好格式,数据提供方按照格式提供数据.数据获取方则按照格式获取数据 iOS开发常见的解析:XML解析.JSO ...
- jQuery解析JSON的问题
在WEB数据传输过程中,json是以文本,即字符串的轻量级形式传递的,而客户端一般用JS操作的是接收到的JSON对象,所以,JSON对象和JSON字符串之间的相互转换.JSON数据的解析是关键. JS ...
- Json转model对象,model转json,解析json字符串
GitHub链接: https://github.com/mozhenhau/D3Json D3Json 通过swift的反射特性,把json数据转换为model对象,本类最主要是解决了其他一般jso ...
- Android数据解析-JSON解析
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,基于JavaScript(Standard ECMA-262 3rd Edition - December ...
- Java解析json(二):jackson
Java解析json(二):jackson 官方参考 Jackson Home Page:https://github.com/FasterXML/jackson Jackson Wiki:htt ...
- $Java-json系列(一):用GSON解析Json格式数据
GSON是谷歌提供的开源库,用来解析Json格式的数据,非常好用.如果要使用GSON的话,则要先下载gson-2.2.4.jar这个文件,如果是在Android项目中使用,则在Android项目的li ...
- Gson+GsonFormat+Postman简单粗暴解析json
现在有时候之前的项目需要返回来修改bug看到以下这段代码 if (test != null) { JSONTokener jsonParser = new JSONTokener(test); JSO ...
随机推荐
- fast-json.jar的用法
fast-json.jar 解析json数据:一种json数据解析方式是这种,点击这里下载jsonfast.jar+fastjsonAPI文档 [ { "id": 6378, &q ...
- iOS--Swift开发中的单例设计模式
最近在开发一个小的应用,遇到了一些Objective-c上面常用的单例模式,但是swift上面还是有一定区别的,反复倒来倒去发现不能按常理(正常的oc to swift的方式)出牌,因此搜索了一些帖子 ...
- Goldeneye.py网站压力测试工具2.1版源码
Goldeneye压力测试工具的源代码,粗略看了下,代码写的蛮规范和易读的,打算边读边加上了中文注释,但是想来也没太大必要,代码600多行,值得学习的地方还是蛮多的,喜欢Python的同学可以一读 这 ...
- iSwifting社区【www.iSwifting.com】招聘版主
iSwifting社区[www.iSwifting.com]昨天找来几个主持人.我已经被任命为他们的任务领域. 他们有百度的project噢,还有cocoaChina问答区的活跃人物! 欢迎大家一起学 ...
- 确保Zend Studio最佳性能的10点建议
作为一个PHP开发人员,你需要知道使用Zend Studio时,什么应该做,什么要避免.就像Roy Ganor说的那样“你必须掌握的你IDE”.从IDE角度来看,建立PHP项目时,了解Zend Stu ...
- HDU 4812 D Tree 树分区+逆+hash新位置
意甲冠军: 特定n点树 K 以下n号码是正确的点 以下n-1行给出了树的侧. 问: 所以,如果有在正确的道路点图的路径 % mod = K 如果输出路径的两端存在. 多条路径则输出字典序最小的一条. ...
- Android-往来:包Group添加到联系人
long groupId = Constant.createGroupId; ContentValues values = new ContentValues(); for(int i=0,len=C ...
- log4net项目中如何配置,以下详解
log4net.config配置文件 <?xml version="1.0" encoding="utf-8"?> <log4net debu ...
- 我的Android 4 学习系列之创建应用程序和Activity:Manifest、Application、Activity
目录 介绍Android应用程序组件,以及使用这些组件构建的各种Android应用程序 Android应用程序的生命周期 如何创建应用程序Manifest 如何使用外部资源提供对位置.语言和硬件配置的 ...
- word-wrap同word-break的区别
兼容 IE 和 FF 的换行 CSS 推荐样式 最好的方式是 以下是引用片段: word-wrap:break-word; overflow:hidden; 而不是 以下是引用片段: word-wra ...