当json.js遇见dynamic.net [0]

时间:2020-12-14 18:53:00

各位不明真相的围观群众大家好,我承认自己有些标题党了,其实真正的题目应该是‘使用.NET4的dynamic类型与json数据相互映射’ :) (可是这个名字未免也太撮了点)

.NET4之前,数据的序列化都是基于某个具体类型,比如先要定义一个C# class,然后attribute,serializer... javascript则是动态语言,可以动态变化自己的属性(所谓的expando对象)。我们创建一个js对象var obj={}之后可以不断增加新属性,如obj.color='red'。正是由于类型是个弱化的概念,所以js常被称为object-based(基于对象)而非object-oriented(面向对象)。就像鸡不同鸭讲,静态语言与动态语言互动起来是比较吃力的(假设:讲=数据映射)。.NET4推动了对动态语言从底层基础设施(DLR)一直到上层语法建设(dynamic keyword)的支持。接下来的几篇会介绍如何使用.NET4的新特性实现一个能够轻松转换json的mini-library。先来看一下我们的目标:

设计理念

    1. 大家都很忙,所以整个代码篇幅一定要短。准备将非注释内容控制在150行之内,每个方法在10行之内。这样的话,‘肉’少‘骨骼’清晰,能够很容易的阅读,一扫就能看完,迅速把握重点。
    2. 为了追求‘高纯度’,异常处理的细活就留给大家去完善了。可能会使用很紧凑的代码风格,比如链式访问,pipeline化操作。
    3. 能够使C#代码模仿出json的风格,或者说尽量的接近。json数据的语法噪音算是相当小的(js真是了不起,好像语法都没啥变化额)。
    4. 支持常用的json数据类型,支持理论上的无限层次。

      再来看一下几种可能的使用场景(通过愿景来反向设计)

      JSON风格

      假设定义DJson封装json object{}的处理逻辑,子类DJsonArray:DJson负责json array[]。

        
        
        
      public class DJson ...
      public class DJsonArray : DJson ...

      “Jane今年24岁,有个32的神秘男友Jesse,你看他的手机号多牛X...”将被表示成

        
        
        
      dynamic data = DJson.Wrap( new {
      name
      = " Jane " ,
      male
      = false ,
      age
      = 24 ,
      dob
      = DateTime.Now,
      friend
      = new {
      name
      = " Jesse " ,
      male
      = true ,
      age
      = 32 ,
      dob
      = DateTime.Now},
      mobile
      = new object []{ new []{ 86 }, 13888888888 },
      });

      对应的JSON是

        
        
        
      {
      " name " : " Jane " ,
      " male " : false ,
      " age " : 24 ,
      " dob " : " \/Date(1296239796269)\/ " ,
      " friend " :{
      " name " : " Jesse " ,
      " male " : true ,
      " age " : 32 ,
      " dob " :
      " \/Date(1296239796270)\/ " },
      " mobile " :[[ 86 ], 13888888888 ]} //(别问我jesse的手机为什么是个数组)
      }

      两者形态上已经很接近了,不过json更胜一筹。

      动态

      js的数组是可以不断添加数据的(这个可以有)

        
        
        
      dynamic data = new DJsonArray();
      data[
      0 ] = new { name = " 小朋盂 1号 " };
      data[
      1 ] = new { name = " 小朋盂 2号 " };
      data[
      2 ] = new { name = " 小朋盂 3号 " };

      对应的JSON是

        
        
        
      [{ " name " : " 小朋盂 1号 " },{ " name " : " 小朋盂 2号 " },{ " name " : " 小朋盂 3号 " }]

      JQuery

      如果可以用到jquery中那就更棒了。比如让c#写配置信息,为jquery输送炮弹。

        
        
        
      $.get( " test.php " , <%= DJson.Wrap( new { choices = new [] { " Jon " , " Susan " } }) %> ); //in an aspx file

      最终呈现是

        
        
        
      $.get( " test.php " , { " choices " : [ " Jon " , " Susan " ]} ); // from http://api.jquery.com/jQuery.get/

      Twitter

      可以很方便的解析一些json数据比如twitter的。

      我从twitter console那里搞了些public timeline的数据(就是首页的最新话题),不方便FQ的请这里下载。格式大致像这样:

        
        
        
      [
      {
      // status 1
      ...
      " text " : " aaaaah liat iklannya nendroidnya black shooter jadi pengeeeeeennnnn " ,
      " id " : 31021719573504000 ,
      ...
      " user " : {
      ...
      " name " : " Dheena Aoi " ,
      ...
      " id " : 27851528 ,
      ...
      " location " : " \u00dcT: -6.909664,107.667199 " ,
      ...
      },
      },
      {
      // status 2 ...

      由JSON转换之后的c#数据应该很容易访问,比如

        
        
        
      var json = System.IO.File.ReadAllText( " c:/twitter.js " );
      dynamic statuses
      = DJson.Parse(json);
      for ( int i = 0 ; i < statuses.Length; i ++ )
      {
      var status
      = statuses[i];
      Console.WriteLine(
      " id: {0}\nname: {1}\nfrom: {2}\ntext: {3}\n " , status.user.id, status.user.name, status.user.location, status.text);
      }

      这样就可以打印出所有微博的相关信息了

        
        
        
      id: 27851528
      name: Dheena Aoi
      from: Brittanny Eleven
      text: aaaaah liat iklannya nendroidnya black shooter jadi pengeeeeeennnnn

      id: 95445857
      name: オレンジ
      from:
      text: デスノートには、「オレンジ 2044年4月10日5:00、「バルス!!」と叫んで死亡
      」と記されています。 http://shindanmaker.com/12516 #deathnotter よし、ひこーせき
      を用意してくれ。みんな道連れd←

      id: 229458542
      name: Edris Mathewson
      from: Utah
      text: :O readings Things One Must Know When Going For Psychic Email Readings ht
      tp://bit.ly/fi9ozw
      ...

      在下一篇中我们将walk through所有的关键技术,然后是设计分析,最后是完整的带注版代码。

      To be continued ...