JayRock的一些用法:json and json rpc for .Net
JayRock的网站:https://bitbucket.org/raboof/jayrock/wiki/Home 注:JayRock是开源的,对应编译好的dll类库对应.net 2.0的和.net 4.0的都有。对于生成json字符串和解析json字符串有几种方式 直接拼接字符串的方式生成,自己按字符串整理格式去解析。 利用jayrock.json以JsonObject,JsonArray这种json特有格式去生成和解析字符串。 通过jayrock.json在C#的数据对象与json字符串之间进行序列化和反序列化的转换。这种序列化与反序列化的方式,很多json组件都能实现,.net .40平台自带的有DataContractJsonSerializer,JavaScriptSerializer,另外也有json.net这些其它的第三方工具库。 JayRock 是用于C#实现json编码数据和json rpc通讯的一个第三方开源类库。 虽然网上分析在json序列化和反序列化上,jayRock的性能不是很高,不过我觉得在访问量不是特别高时,这个类库挺好用的。 json部分 JavaScript Object Notation(简称JSON),即一种开放式和基于文本的数据交换格式,它提供了一种标准数据交换格式,更适用于 Ajax 样式的 Web 应用程序。 Jayrock是一个LGPL的开源的软件,实现了JSON和JSON-RPC,支持微软ASP.NET框架。 JavaScript Object Notation (JSON) 简介 特点: 1、简单格式化的数据交换 2、易于人们的读写习惯 3、易于机器的分析和运行 4、JavaScript中使用eval()方法可以很方便的读取 JSON数据 5、JSON支持多种语言。 语法分析: JSON可以用于封装数据,它是一种类似于C语言家族的语言,所以能很容易被C语言家族的语言分析 1、对象object包含在一对{}中。 2、对象的属性member使用[string : value]成对的表示,属性与属性之间用逗号隔开。 3、数组array包含在一对[]中。 4、元素elements与元素之间用逗号隔开。 5、元素值可具有的类型:string, number, object, array, true, false, null JSON VS XML: ·可读性 JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,很难分出胜负。 ·可扩展性 XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。 ·编码难度 XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。 ·解码难度 XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。 ·流行度 XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous JavaScript and JSON)了。 闲话少说咱继续往下看,编译好的有2个dll, Jayrock.Json.dll 和 Jayrock.dll。Jayrock.Json 库里面比较重要的几个对象: JsonWriter、JsonReader、JsonTextWriter 和 JsonTextReader 模拟 .NET Framework 类 XmlWriter、XmlReader、XmlTextWriter 和 XmlTextReader 的语义。 Jayrock.Json.Conversion.JsonConvert 类提供了用于在 .NET 类型和 JSON 之间进行转换的 Export 和 Import 方法。这些方法提供了分别与 XmlSerializer 类方法 Serialize 和 Deserialize 相似的功能。 创建json 实例胜于一切,让实例说话,看下面的例子。 //创建JSON //创建json数组 using (JsonTextWriter writer = new JsonTextWriter()) { //数组:["China","Japan","Korea","USA","UK"] writer.WriteStartArray(); writer.WriteString("China"); writer.WriteString("Japan"); writer.WriteString("Korea"); writer.WriteString("USA"); writer.WriteString("UK"); writer.WriteEndArray(); Response.Write(writer.ToString() + "<br/>"); } //创建json对象 using (JsonWriter writer = new JsonTextWriter()) { //对象:{"Name":"JackLee","Age":"20"} writer.WriteStartObject(); writer.WriteMember("Name"); writer.WriteString("JackLee"); writer.WriteMember("Age"); writer.WriteString("20"); writer.WriteEndObject(); Response.Write(writer.ToString()); } 解析json //解析JSON string jsonText = @"['Europe', 'Asia', 'Australia', 'Antarctica', 'North America', 'South America', 'Africa']"; using (JsonReader reader = new JsonTextReader(new System.IO.StringReader(jsonText))) { while (reader.Read()) { if (reader.TokenClass == JsonTokenClass.String) { Response.Write(reader.Text); } } } //数组 string[] strArr = JsonConvert.Import(typeof(string[]), jsonText) as string[]; //对象 jsonText = @"{'Name':'JackLee','Age':'20'}"; JsonObject obj = JsonConvert.Import(typeof(JsonObject), jsonText) as JsonObject; obj["Name"] = "Martin"; obj["Age"] = "30"; jsonText = JsonConvert.ExportToString(obj); //结果:{"Name":"Martin","Age":"30"} jsonText = JsonConvert.ExportToString(new string[] { "A", "B", "C", "D" }); //结果:["A","B","C","D"] 序列化与反序列化 参考这篇文章:https://www.cnblogs.com/superfeeling/archive/2012/06/25/2562775.html 实体类User.cs: public class User { public User() { } private int id; public int Id { get { return id; } set { id = value; } } private string name; public string Name { get { return name; } set { name = value; } } private DateTime time; public DateTime Time { get { return time; } set { time = value; } } private double money; public double Money { get { return money; } set { money = value; } } private string[] str; public string[] Str { get { return str; } set { str = value; } } } 把实体转成JSON 把实体类序列化成json字符串 User user = new User(); user.Id = 1; user.Name = "你"; user.Money = 2.3; user.Time = DateTime.Now; user.Str = new string[] { "1", "2", "3" }; Jayrock.Json.JsonTextWriter writer = new Jayrock.Json.JsonTextWriter(); Jayrock.Json.Conversion.JsonConvert.Export(user, writer); string str = writer.ToString(); //str等于{"id":1,"name":"你","time":"2009-04-14T14:29:29.4375000+08:00","money":2.3,"str":["1","2","3"]} JSON转成实体 对json字符串进行反序列化 string str = "{\"id\":1,\"name\":\"你\",\"time\":\"2009-04-13T22:21:11.6562500+08:00\",\"money\":2.3,\"str\":[\"1\",\"2\",\"3\"]}"; User user = (User)Jayrock.Json.Conversion.JsonConvert.Import(typeof(User), str); json rpc部分 我们说过了Jayrock.Json.dll ,回过头来我们再来看看Jayrock.dll,在这个DLL中有Jayrock.JsonRpc.Web .JsonRpcHandler类,我们来看看这个类的一些用法,Jayrock 远程方法要求写在一个ashx中,页面请求这个ashx的时候,在ProcessRequest 中根据Request对象中的参数信息,确定请求的服务器端方法名称和参数,然后进行调用,并返回结果。还是实例先行。 我们添加一个一般处理程序(ashx),将其修改如下: <%@ WebHandler Language="C#" Class="Handler" %> using System; using System.Web; using Jayrock.Json; using Jayrock.JsonRpc; using Jayrock.JsonRpc.Web; public class Handler : JsonRpcHandler { [JsonRpcMethod("greetings")] public string Greetings() { return "Welcome to Jayrock!"; } } 前台代码我们这样写: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script type="text/javascript" src="json.js"></script> <script type="text/javascript" src="Handler.ashx?proxy"></script> <script type="text/javascript"> /*<![CDATA[*/ window.onload = function() { var s = new Handler(); alert(s.greetings()); //同步调用。 s.greetings(function(val) { alert(val.result); //异步调用 }) } /*]]>*/ </script> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html> 注意:在调用一般处理程序时,一定得是src="Handler.ashx?proxy",要加上一个参数proxy。这样会自动生成一个代理js。如果想要看这个代理js,在地址栏里直接请求Handler.ashx?proxy,就可下下载到一个js文件。效果如下: // This JavaScript was automatically generated by // Jayrock.JsonRpc.Web.JsonRpcProxyGenerator, Jayrock, Version=0.9.8316.0, Culture=neutral, PublicKeyToken=null // on 2010年4月20日 at 11:59:15 (中国标准时间) // Proxy version 1.0 function Handler(url) { this["greetings"] = function(callback) { return call("greetings", [ ], callback); } /* Returns an array of method names implemented by this service. */ this["system.listMethods"] = function(callback) { return call("system.listMethods", [ ], callback); } /* Returns the version server implementation using the major, minor, build and revision format. */ this["system.version"] = function(callback) { return call("system.version", [ ], callback); } /* Returns a summary about the server implementation for display purposes. */ this["system.about"] = function(callback) { return call("system.about", [ ], callback); } var url = typeof(url) === 'string' ? url : 'http://localhost:17650/JayRock_Json/Handler.ashx'; var self = this; var nextId = 0; function call(method, params, callback) { var request = { id : nextId++, method : method, params : params }; return callback == null ? callSync(method, request) : callAsync(method, request, callback); } function callSync(method, request) { var http = newHTTP(); http.open('POST', url, false, self.httpUserName, self.httpPassword); setupHeaders(http, method); http.send(JSON.stringify(request)); if (http.status != 200) throw { message : http.status + ' ' + http.statusText, toString : function() { return message; } }; var response = JSON.eval(http.responseText); if (response.error != null) throw response.error; return response.result; } function callAsync(method, request, callback) { var http = newHTTP(); http.open('POST', url, true, self.httpUserName, self.httpPassword); setupHeaders(http, method); http.onreadystatechange = function() { http_onreadystatechange(http, callback); } http.send(JSON.stringify(request)); return request.id; } function setupHeaders(http, method) { http.setRequestHeader('Content-Type', 'text/plain; charset=utf-8'); http.setRequestHeader('X-JSON-RPC', method); } function http_onreadystatechange(sender, callback) { if (sender.readyState == /* complete */ 4) { var response = sender.status == 200 ? JSON.eval(sender.responseText) : {}; response.xmlHTTP = sender; callback(response); } } function newHTTP() { if (typeof(window) != 'undefined' && window.XMLHttpRequest) return new XMLHttpRequest(); /* IE7, Safari 1.2, Mozilla 1.0/Firefox, and Netscape 7 */ else return new ActiveXObject('Microsoft.XMLHTTP'); /* WSH and IE 5 to IE 6 */ } } Handler.rpcMethods = ["greetings","system.listMethods","system.version","system.about"];
========================================================================================================================================================== 另外关于json-rpc的用法,可以参考这篇文章 https://www.cnblogs.com/EasonJim/p/4706266.html
使用Jayrock开源组件开发基于JSON-RPC协议的接口
最近接手一个以前的项目,无意间发现此项目开发接口的组件:Jayrock(接口组件估计用的少,用的最多的估计是这个Jayrock.json.dll,用于解析json)
以下是Jayrock的介绍官网:
https://atifaziz.github.io/projects/jayrock/
如果你在开发上使用了该组件,上面的官网会是一个不错的入门教程。
在研究的过程中,发现Jayrock有以下的特定,主要从开发角度方向进行分析。
优点如下:
1、接口开发和部署简单,直接继承组件的JsonRpcHandler,然后进行自己的业务开发,然而,你可以使用实体的ashx文件或者在web.config中全局接管httphandler的方式使用;
2、有接口的帮助页面和测试页面,这个方式其实非常适合移动端或者第三方需要调用的人员使用,能快速的了解接口的用途和测试数据返回的json格式;
3、本域调用后台的接口时,直接使用proxy模式,在html的页面自动生成一个接口js调用类直接使用方法的形式调用接口,抛弃的传统的写请求的方式(确实节省前端开发人员的工作量);
4、跨域时,只要在后台代码开发的接口上,标志跨域标识,直接使用getrpc模式,即可轻松的进行跨域调用(跨域的JS只能是GET方式获取),但是每一个接口的代码就得自己写了;
5、接口json格式采用了jsonrpc格式,对于json的定义,提供了统一性;
缺点,也是美中不足的吧:
1、由于整个组件采用jsonrpc格式,那么组件在封装的时候,就上传照片或者文件来说,完全没有考虑会使用流的形式,只能讲文件转成base64格式,然后装载进json字段中,一并提交;那么问题来了,base64讲图片转换之后,数据就会变的大很多,流量损失比较大;
2、虽然方法可以写注释,但是针对每个参数的注释确没有,可能是作者的思路是,参数命名直观即可;
3、接口的参数上,每个都是必须的,不能不传递,但是我们开发接口的时候,有些特定的需求,会使一些参数传递为null,比如搜索接口就是一个典型的例子;(此观点是错误的,经过深入研究,已经解决,详细请看此篇文章)
4、整体采用jsonrpc协议后,流量上自然是大了那么一丁点的了,但是,对于一般的业务系统而言,这些可以忽略不计;
以下是我在开发上的一些图片流程:
1、接口的开发
1)物理文件模式:
2)web.config接管模式
2、接口的帮助页面和测试页面
1)帮助页面,清晰了然
2)接口的测试页面,自动展示出哪些参数,给移动端开发确实是不错选择
3、本域调用:
是不是非常的简单,非常的爽;
4、跨域调用形式,这个算是我艰辛万苦在老外的一个网站上的一个问题上找到的
使用非常的简单,只要在接口上标记Idempotent = true即可,然后如下调用即可:
5、JSON-RPC协议说明,直接引入网址:http://www.json-rpc.org/
http://blog.csdn.net/hahahacff/article/details/29119077
总结:
以上就是我对Jayrock组件的研究,其实,以上说到的优点mvc的web api就能全部实现了,帮助和测试页面只需在nuget上下载个扩展即可;
以下是组件的全部文件,包括一些例子也在里面,由于谷歌代码管理即将关闭(只是改为只读模式),所以我整理了一份最全的:(链接: https://pan.baidu.com/s/1jIECHNK 密码: nvee)
如果要更好的开发体验,那么可以尝试以下升级版本:http://www.cnblogs.com/EasonJim/p/6027234.html