ComponentositeモードでJSONを構築する

12756 ワード

Jsonは現在流行しているAjaxまたはServiceデータ交換フォーマットです.NETでは、DataContractJsonSerializer(System.Runtime.Serialization.Jsonネーミングスペース)を使用して、json文字列とエンティティオブジェクト間を容易に変換できます.
Restful WCFサービス・サイトでは、Jsonをコード・シーケンス化する必要はありません.サービスはデフォルトでxml形式で結果を返しますが、Webリクエストヘッダ情報のAcceptプロパティがアプリケーション/jsonの場合、クライアントはjson形式で結果をシーケンス化します.
クライアントがjqueryで実現するのは簡単で、ajax関数を呼び出したときにdataType:'json'を設定すればよい.
クライアントは、要求ヘッダのContentTypeをtext/json(jqueryのajax関数にもこの属性がある)に設定すると、サービスは自動的に要求内容をエンティティに逆シーケンス化するjsonをサービス処理に送信することもできる.
しかし、多くの場合、私たちが出力したjsonは標準的なエンティティの集合ではなく、個別の属性だけを出力したり、ページングクエリなどの他のものを混ぜたりする可能性があります.私たちはお客様に返された結果セットが何ページ目で、全部で何ページあるかを教えて、このようなjsonは私たち自身でコードを通じて出力しなければなりません.これは煩わしくて、業務が複雑で仕方がありませんが、それらの単引双引を書いて、括弧の角の括弧を使って、いつも転義しなければなりませんが、少しも面白くありません.たとえば、最も単純なエンティティ:
var sb = new StringBuilder("[");

foreach (var user in lstUser)

{

    sb.AppendFormat("{{'name':'{0}','email':'{1}'}},",user.Name,user.Email);

}

sb.Remove(sb.Length - 1, 1);

sb.Append("]");


このコードを一度に書くことができる人は、決して等閑な人ではありません.私が下書きをしたときも書き間違えた.相形の下で、jsonの長兄xmlは多くの力を与えて、中のすべての操作が対象を通過することができるため、例えばXAttribute、XText、XCommentなど.
class Program

{

    static void Main()

    {

        var lstUser = new List<User>{

            new User { Name = "   ",  Email="[email protected]"},

            new User { Name = "  ",  Email="[email protected]"},

            new User { Name = "   ",  Email="[email protected]"}               

        };



        var xe = new XElement("Users",

            from u in lstUser

            select new XElement("User",

                new XAttribute("name", u.Name),

                new XAttribute("email", u.Email)));



        Console.WriteLine(xe);

        Console.ReadLine();

    }



    class User

    {

        public string Name { get; set; }

        public string Email { get; set; }

    }

}


優雅な5行のコードは、潘金蓮と彼女の最も重要な2人の男をスマートに縛った.Jsonを書くのもこんなに優雅で、完全にできて、実は私达はとっくにJson.Netがあって、ヘビー級のボクサー、私は感じて、私达の日常の応用を游ぶのは高射砲でスズメを打つようで、やはり弓を弾くほうがお得です.
XNodeに倣って、いくつかのJsonオブジェクトタイプを定義します.
/// <summary>

///   json  

/// </summary>

class JArray : JElement

{

    public JArray(params object[] array)

    {

        this.Elements = array.Select(o =>

        {

            var element = o as JElement;

            if (element == null) return new JElement(o);

            else return element;

        }).ToList();

    }



    public List<JElement> Elements { get; set; }



    public override string ToString()

    {

        return "[" + String.Join(",", this.Elements) + "]";

    }

}



/// <summary>

///   json    

/// </summary>

class JEntity : JElement

{

    public JEntity(params JProperty[] properties)

    {        

        this.Value = properties.ToList();

    }



    public List<JProperty> Properties { get { return this.Value as List<JProperty>; } }



    public override string ToString()

    {

        return "{" + String.Join(",", this.Properties) + "}";

    }

}



/// <summary>

///     json        

/// </summary>

class JProperty 

{

    public JProperty(string name, object value)

    {

        this.Name = name;



        var element = value as JElement;

        if (element == null) element = new JElement(value);

        this.Value = element;

    }



    public string Name { get; set; }



    public JElement Value { get; set; }



    public override string ToString()

    {

        return "'" + Name + "':'" + Value + "'";

    }

}



/// <summary>

///      json  

/// </summary>

class JElement

{

    public JElement() { }



    public JElement(object value)

    {

        var array = value as System.Collections.IEnumerable;



        if (array != null && !(value is string))

        {

            this.Value = new JArray(array.Cast<object>().ToArray());

        }

        else this.Value = value;

    }



    public object Value { get; set; }



    public override string ToString()

    {

        var type = Value.GetType();

        if (type.IsPrimitive)

        {

            if (type == typeof(int) || type == typeof(double)) return Value.ToString();

        }



        return "'" + Value + "'";

    }

}


そして、jsonと書くことができます.ほら、xmlを出力する書き方に似ていますね.
var json = new JArray(

    (from u in lstUser

    select new JEntity(

        new JProperty("name", u.Name),

        new JProperty("email", u.Email))).ToArray());



Console.WriteLine(json);


ところでjsonはもともと軽量レベルのデータ交換フォーマットであり,軽量レベルのフォーマットも軽量な方法で処理すべきであり,また再利用できることが最も重要であることは一目瞭然であり,この方式を考慮することができる.JArrayなどいくつかのコンストラクション関数については,さらに改善が必要である.
最近の研究を経て、このような優雅な方式json構造方式は、江湖至高、OOP兵法23条の中のCompositeモード(「.Net設計モード」第9章)に暗合しているのではないかと発見された.何気なく至尊の宝典の道を覗かなければならない.わあ、すばらしい!
最近、jsonにはjsonpという弟がいて、火星になった.もともとBingMap APIのスクリプトロード方式で、よく使われているが、まだぼんやりしている.
今は自分でサーバー側を書く番で、WCFの自動変換の優美さを破壊したくないので、出力で置き換えたいのですが、Resonseを設定します.Filter(リファレンス)は面倒くさいし、Response.OutputStreamは書けないし読めない.グローバルイベントに応答して、本文の開始前にクライアントコールバックの関数名とカッコを書き込み、本文の出力が終了した後にカッコを追加するしかありません.とっくに知っていたが、书くたびに、私の心はかすかに痛くて、葛藤していた.