2009-02-20 8 views
30

コミュニティ内のJSONライブラリの人々が.NETの中でどのように使用しているのか聞いてみたいと思いますか? .NET(C#)内からいくつかのJSONオブジェクトグラフを解析してシリアル化する必要があります。私は自分自身をロールバックすることができますが、人々が使用している確かなライブラリがあれば、あなたのコメントを聞きたいと思います。私はjson.orgサイトの図書館のリストを見ましたが、それはかなり大きいリストであり、コミュニティは通常、嫌悪者からの競争者を吟味するのにうってつけです.NETでうまくいくJSONライブラリは何ですか?

あなたのライブラリの経験の賛否両論信じられないほど役に立つだろう。 - 前もって感謝します。

答えて

22

私はJson.NETを過去に成功させました。サイトから

例:

Product product = new Product(); 
product.Name = "Apple"; 
product.Expiry = new DateTime(2008, 12, 28); 
product.Price = 3.99M; 
product.Sizes = new string[] { "Small", "Medium", "Large" }; 

string json = JsonConvert.SerializeObject(product); 
//{ 
// "Name": "Apple", 
// "Expiry": new Date(1230422400000), 
// "Price": 3.99, 
// "Sizes": [ 
// "Small", 
// "Medium", 
// "Large" 
// ] 
//} 

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json); 
+5

誰かがこの問題を遭遇した場合、「Expiry」:new Date(1230422400000) 'は**有効なJSONではありません。 –

+0

@ RichardMarskell-Drackir、はい。 JSON.NETはかなり良いライブラリですが、その部分は悪い例です。私はそれがまだデフォルトの動作であるかどうかはわかりませんが、この(古い)[記事](http://james.newtonking.com/archive/2009/02/20/good-date-times-with-json- net.aspx)では、['IsoDateTimeConverter'](http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_Converters_IsoDateTimeConverter.htm)を使用して、(有効な)ISO日付文字列とのシリアル化を行うことができます。 –

10

私はSystem.ServiceModel.Web.dllアセンブリ内DataContractJsonSerializerを使用して独自のJSONシリアライザを書いた[標準アセンブリとして、および.NETで.NET 3.5をWCFのコンポーネントに含まれています3.5 SP1クライアントプロファイル](.NET 4.0およびSilverlight 4では、System.Runtime.Serialization.dllに移動されました)。

using System.IO; 
using System.Runtime.Serialization.Json; 

public class JsonObjectSerializer 
{ 
    public string Serialize<T>(T instance) where T : class 
    { 
     var serializer = new DataContractJsonSerializer(typeof(T)); 
     using (var memoryStream = new MemoryStream()) 
     { 
      serializer.WriteObject(memoryStream, instance); 

      memoryStream.Flush(); 
      memoryStream.Position = 0; 

      using (var reader = new StreamReader(memoryStream)) 
      { 
       return reader.ReadToEnd(); 
      } 
     } 
    } 

    public T Deserialize<T>(string serialized) where T : class 
    { 
     var serializer = new DataContractJsonSerializer(typeof(T)); 
     using (var memoryStream = new MemoryStream()) 
     { 
      using (var writer = new StreamWriter(memoryStream)) 
      { 
       writer.Write(serialized); 
       writer.Flush(); 

       memoryStream.Position = 0; 

       return serializer.ReadObject(memoryStream) as T; 
      } 
     } 
    } 
} 
+1

自分で拡張メソッドに調整しました。ありがとう:) –

+0

DataContractJsonSerializerがJSONの代わりにXMLを返すのを防ぐにはどうすればいいですか? – devlord

3

.NET 3.5に含まれているSystem.Runtime.Serialization.Json名前空間を確認してください。

+7

興味のある方は、System.ServiceModel.Webにあります。 –

+1

-1これまでに追加された内容がわかるまで、http://stackoverflow.com/questions/571168/what-json-library-works-well-for- you-in-net/571200#571200これは、 –

+1

の前に投稿されました。フレームワークバージョンを含めると、*簡潔になります。 –

19

少なくとも2つがフレームワークに組み込まれています。

新しい:System.Runtime.Serialization.Json

と古い:System.Web.Script.Serialization

私はサードパーティのライブラリの依存関係を持っていないことを好みます。私は毎日JSONを使って作業しており、フレームワークに既に存在するものよりも何も必要なことはありません。

+1

エンコードにはうってつけですが、私はSystem.Web.Helpers.Json.Decode(文字列)を使用していました。私はエンコードにも使用しました。 – Wout

+2

小さいオブジェクトの場合は問題なく動作します。一度大きなオブジェクトや重い使用になると、組み込みライブラリのパーフォンスは不足しています。 JSON.Netに切り替えるだけでシリアライズとデシリアライズを50%以上削減できました。 – CertifiedCrazy

5

また、私のServiceStack JsonSerializerを試してみてください - それは現時点based on the benchmarks of the leading JSON serializersで最速.NET JSONシリアライザだと、インタフェース、継承、匿名型を含む遅延バインディングオブジェクトなど任意のPOCOタイプ、DataContracts、リスト/辞書をシリアル化をサポートしてい

基本例:

Customer customer = new Customer { Name="Joe Bloggs", Age=31 }; 
string json = customer.ToJson(); 
Customer fromJson = json.FromJson<Customer>(json); 
+1

残念ながら、これはAGPLライセンスでリリースされています。つまり、Webサイトを開発していても、オープンソースソフトウェアでのみ**使用できます。 –

+1

v3はBSDライセンスを受けていますが、最新のv4は[商用ライセンス](https://servicestack.net/text#pricing)でも入手できます。 – mythz

+1

v3はどこで入手できますか? ** \ [編集] **気にしないで、それを見つけました:https://github.com/ServiceStack/ServiceStack.Text/releases/tag/v3-snapshot –

2

私はグーグルに「JSON」と入力し、トップヒットは、良好な単ユーティリティクラスのように見えるものにつながる、json.orgた:

using System; 
using System.Collections; 
using System.Globalization; 
using System.Text; 

namespace Procurios.Public 
{ 
    /// <summary> 
    /// This class encodes and decodes JSON strings. 
    /// Spec. details, see http://www.json.org/ 
    /// 
    /// JSON uses Arrays and Objects. These correspond here to the datatypes ArrayList and Hashtable. 
    /// All numbers are parsed to doubles. 
    /// </summary> 
    public class JSON 
    { 
     public const int TOKEN_NONE = 0; 
     public const int TOKEN_CURLY_OPEN = 1; 
     public const int TOKEN_CURLY_CLOSE = 2; 
     public const int TOKEN_SQUARED_OPEN = 3; 
     public const int TOKEN_SQUARED_CLOSE = 4; 
     public const int TOKEN_COLON = 5; 
     public const int TOKEN_COMMA = 6; 
     public const int TOKEN_STRING = 7; 
     public const int TOKEN_NUMBER = 8; 
     public const int TOKEN_TRUE = 9; 
     public const int TOKEN_FALSE = 10; 
     public const int TOKEN_NULL = 11; 

     private const int BUILDER_CAPACITY = 2000; 

     /// <summary> 
     /// Parses the string json into a value 
     /// </summary> 
     /// <param name="json">A JSON string.</param> 
     /// <returns>An ArrayList, a Hashtable, a double, a string, null, true, or false</returns> 
     public static object JsonDecode(string json) 
     { 
      bool success = true; 

      return JsonDecode(json, ref success); 
     } 

     /// <summary> 
     /// Parses the string json into a value; and fills 'success' with the successfullness of the parse. 
     /// </summary> 
     /// <param name="json">A JSON string.</param> 
     /// <param name="success">Successful parse?</param> 
     /// <returns>An ArrayList, a Hashtable, a double, a string, null, true, or false</returns> 
     public static object JsonDecode(string json, ref bool success) 
     { 
      success = true; 
      if (json != null) { 
       char[] charArray = json.ToCharArray(); 
       int index = 0; 
       object value = ParseValue(charArray, ref index, ref success); 
       return value; 
      } else { 
       return null; 
      } 
     } 

     /// <summary> 
     /// Converts a Hashtable/ArrayList object into a JSON string 
     /// </summary> 
     /// <param name="json">A Hashtable/ArrayList</param> 
     /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns> 
     public static string JsonEncode(object json) 
     { 
      StringBuilder builder = new StringBuilder(BUILDER_CAPACITY); 
      bool success = SerializeValue(json, builder); 
      return (success ? builder.ToString() : null); 
     } 

     protected static Hashtable ParseObject(char[] json, ref int index, ref bool success) 
     { 
      Hashtable table = new Hashtable(); 
      int token; 

      // { 
      NextToken(json, ref index); 

      bool done = false; 
      while (!done) { 
       token = LookAhead(json, index); 
       if (token == JSON.TOKEN_NONE) { 
        success = false; 
        return null; 
       } else if (token == JSON.TOKEN_COMMA) { 
        NextToken(json, ref index); 
       } else if (token == JSON.TOKEN_CURLY_CLOSE) { 
        NextToken(json, ref index); 
        return table; 
       } else { 

        // name 
        string name = ParseString(json, ref index, ref success); 
        if (!success) { 
         success = false; 
         return null; 
        } 

        // : 
        token = NextToken(json, ref index); 
        if (token != JSON.TOKEN_COLON) { 
         success = false; 
         return null; 
        } 

        // value 
        object value = ParseValue(json, ref index, ref success); 
        if (!success) { 
         success = false; 
         return null; 
        } 

        table[name] = value; 
       } 
      } 

      return table; 
     } 

     protected static ArrayList ParseArray(char[] json, ref int index, ref bool success) 
     { 
      ArrayList array = new ArrayList(); 

      // [ 
      NextToken(json, ref index); 

      bool done = false; 
      while (!done) { 
       int token = LookAhead(json, index); 
       if (token == JSON.TOKEN_NONE) { 
        success = false; 
        return null; 
       } else if (token == JSON.TOKEN_COMMA) { 
        NextToken(json, ref index); 
       } else if (token == JSON.TOKEN_SQUARED_CLOSE) { 
        NextToken(json, ref index); 
        break; 
       } else { 
        object value = ParseValue(json, ref index, ref success); 
        if (!success) { 
         return null; 
        } 

        array.Add(value); 
       } 
      } 

      return array; 
     } 

     protected static object ParseValue(char[] json, ref int index, ref bool success) 
     { 
      switch (LookAhead(json, index)) { 
       case JSON.TOKEN_STRING: 
        return ParseString(json, ref index, ref success); 
       case JSON.TOKEN_NUMBER: 
        return ParseNumber(json, ref index, ref success); 
       case JSON.TOKEN_CURLY_OPEN: 
        return ParseObject(json, ref index, ref success); 
       case JSON.TOKEN_SQUARED_OPEN: 
        return ParseArray(json, ref index, ref success); 
       case JSON.TOKEN_TRUE: 
        NextToken(json, ref index); 
        return true; 
       case JSON.TOKEN_FALSE: 
        NextToken(json, ref index); 
        return false; 
       case JSON.TOKEN_NULL: 
        NextToken(json, ref index); 
        return null; 
       case JSON.TOKEN_NONE: 
        break; 
      } 

      success = false; 
      return null; 
     } 

     protected static string ParseString(char[] json, ref int index, ref bool success) 
     { 
      StringBuilder s = new StringBuilder(BUILDER_CAPACITY); 
      char c; 

      EatWhitespace(json, ref index); 

      // " 
      c = json[index++]; 

      bool complete = false; 
      while (!complete) { 

       if (index == json.Length) { 
        break; 
       } 

       c = json[index++]; 
       if (c == '"') { 
        complete = true; 
        break; 
       } else if (c == '\\') { 

        if (index == json.Length) { 
         break; 
        } 
        c = json[index++]; 
        if (c == '"') { 
         s.Append('"'); 
        } else if (c == '\\') { 
         s.Append('\\'); 
        } else if (c == '/') { 
         s.Append('/'); 
        } else if (c == 'b') { 
         s.Append('\b'); 
        } else if (c == 'f') { 
         s.Append('\f'); 
        } else if (c == 'n') { 
         s.Append('\n'); 
        } else if (c == 'r') { 
         s.Append('\r'); 
        } else if (c == 't') { 
         s.Append('\t'); 
        } else if (c == 'u') { 
         int remainingLength = json.Length - index; 
         if (remainingLength >= 4) { 
          // parse the 32 bit hex into an integer codepoint 
          uint codePoint; 
          if (!(success = UInt32.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) { 
           return ""; 
          } 
          // convert the integer codepoint to a unicode char and add to string 
          s.Append(Char.ConvertFromUtf32((int)codePoint)); 
          // skip 4 chars 
          index += 4; 
         } else { 
          break; 
         } 
        } 

       } else { 
        s.Append(c); 
       } 

      } 

      if (!complete) { 
       success = false; 
       return null; 
      } 

      return s.ToString(); 
     } 

     protected static double ParseNumber(char[] json, ref int index, ref bool success) 
     { 
      EatWhitespace(json, ref index); 

      int lastIndex = GetLastIndexOfNumber(json, index); 
      int charLength = (lastIndex - index) + 1; 

      double number; 
      success = Double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); 

      index = lastIndex + 1; 
      return number; 
     } 

     protected static int GetLastIndexOfNumber(char[] json, int index) 
     { 
      int lastIndex; 

      for (lastIndex = index; lastIndex < json.Length; lastIndex++) { 
       if ("-.eE".IndexOf(json[lastIndex]) == -1) { 
        break; 
       } 
      } 
      return lastIndex - 1; 
     } 

     protected static void EatWhitespace(char[] json, ref int index) 
     { 
      for (; index < json.Length; index++) { 
       if (" \t\n\r".IndexOf(json[index]) == -1) { 
        break; 
       } 
      } 
     } 

     protected static int LookAhead(char[] json, int index) 
     { 
      int saveIndex = index; 
      return NextToken(json, ref saveIndex); 
     } 

     protected static int NextToken(char[] json, ref int index) 
     { 
      EatWhitespace(json, ref index); 

      if (index == json.Length) { 
       return JSON.TOKEN_NONE; 
      } 

      char c = json[index]; 
      index++; 
      switch (c) { 
       case '{': 
        return JSON.TOKEN_CURLY_OPEN; 
       case '}': 
        return JSON.TOKEN_CURLY_CLOSE; 
       case '[': 
        return JSON.TOKEN_SQUARED_OPEN; 
       case ']': 
        return JSON.TOKEN_SQUARED_CLOSE; 
       case ',': 
        return JSON.TOKEN_COMMA; 
       case '"': 
        return JSON.TOKEN_STRING; 
       case '0': case '1': case '2': case '3': case '4': 
       case '5': case '6': case '7': case '8': case '9': 
       case '-': 
        return JSON.TOKEN_NUMBER; 
       case ':': 
        return JSON.TOKEN_COLON; 
      } 
      index--; 

      int remainingLength = json.Length - index; 

      // false 
      if (remainingLength >= 5) { 
       if (json[index] == 'f' && 
        json[index + 1] == 'a' && 
        json[index + 2] == 'l' && 
        json[index + 3] == 's' && 
        json[index + 4] == 'e') { 
        index += 5; 
        return JSON.TOKEN_FALSE; 
       } 
      } 

      // true 
      if (remainingLength >= 4) { 
       if (json[index] == 't' && 
        json[index + 1] == 'r' && 
        json[index + 2] == 'u' && 
        json[index + 3] == 'e') { 
        index += 4; 
        return JSON.TOKEN_TRUE; 
       } 
      } 

      // null 
      if (remainingLength >= 4) { 
       if (json[index] == 'n' && 
        json[index + 1] == 'u' && 
        json[index + 2] == 'l' && 
        json[index + 3] == 'l') { 
        index += 4; 
        return JSON.TOKEN_NULL; 
       } 
      } 

      return JSON.TOKEN_NONE; 
     } 

     protected static bool SerializeValue(object value, StringBuilder builder) 
     { 
      bool success = true; 

      if (value is string) { 
       success = SerializeString((string)value, builder); 
      } else if (value is Hashtable) { 
       success = SerializeObject((Hashtable)value, builder); 
      } else if (value is ArrayList) { 
       success = SerializeArray((ArrayList)value, builder); 
      } else if (IsNumeric(value)) { 
       success = SerializeNumber(Convert.ToDouble(value), builder); 
      } else if ((value is Boolean) && ((Boolean)value == true)) { 
       builder.Append("true"); 
      } else if ((value is Boolean) && ((Boolean)value == false)) { 
       builder.Append("false"); 
      } else if (value == null) { 
       builder.Append("null"); 
      } else { 
       success = false; 
      } 
      return success; 
     } 

     protected static bool SerializeObject(Hashtable anObject, StringBuilder builder) 
     { 
      builder.Append("{"); 

      IDictionaryEnumerator e = anObject.GetEnumerator(); 
      bool first = true; 
      while (e.MoveNext()) { 
       string key = e.Key.ToString(); 
       object value = e.Value; 

       if (!first) { 
        builder.Append(", "); 
       } 

       SerializeString(key, builder); 
       builder.Append(":"); 
       if (!SerializeValue(value, builder)) { 
        return false; 
       } 

       first = false; 
      } 

      builder.Append("}"); 
      return true; 
     } 

     protected static bool SerializeArray(ArrayList anArray, StringBuilder builder) 
     { 
      builder.Append("["); 

      bool first = true; 
      for (int i = 0; i < anArray.Count; i++) { 
       object value = anArray[i]; 

       if (!first) { 
        builder.Append(", "); 
       } 

       if (!SerializeValue(value, builder)) { 
        return false; 
       } 

       first = false; 
      } 

      builder.Append("]"); 
      return true; 
     } 

     protected static bool SerializeString(string aString, StringBuilder builder) 
     { 
      builder.Append("\""); 

      char[] charArray = aString.ToCharArray(); 
      for (int i = 0; i < charArray.Length; i++) { 
       char c = charArray[i]; 
       if (c == '"') { 
        builder.Append("\\\""); 
       } else if (c == '\\') { 
        builder.Append("\\\\"); 
       } else if (c == '\b') { 
        builder.Append("\\b"); 
       } else if (c == '\f') { 
        builder.Append("\\f"); 
       } else if (c == '\n') { 
        builder.Append("\\n"); 
       } else if (c == '\r') { 
        builder.Append("\\r"); 
       } else if (c == '\t') { 
        builder.Append("\\t"); 
       } else { 
        int codepoint = Convert.ToInt32(c); 
        if ((codepoint >= 32) && (codepoint <= 126)) { 
         builder.Append(c); 
        } else { 
         builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0')); 
        } 
       } 
      } 

      builder.Append("\""); 
      return true; 
     } 

     protected static bool SerializeNumber(double number, StringBuilder builder) 
     { 
      builder.Append(Convert.ToString(number, CultureInfo.InvariantCulture)); 
      return true; 
     } 

     /// <summary> 
     /// Determines if a given object is numeric in any way 
     /// (can be integer, double, null, etc). 
     /// 
     /// Thanks to mtighe for pointing out Double.TryParse to me. 
     /// </summary> 
     protected static bool IsNumeric(object o) 
     { 
      double result; 

      return (o == null) ? false : Double.TryParse(o.ToString(), out result); 
     } 
    } 
} 
1

私は、エンコードとデコードにSystem.Web.Helpers.Jsonを使用しました。これは動的な型にデコードします。これはjavascriptの動的データに適しています。

関連する問題