I'd be interested in hearing what JSON library folks in the community have been using inside of .NET? I have a need to parse/serialize some JSON object graphs from inside .NET (C#) to actual .NET types. I could roll my own, but if there are some solid libraries folks have used, I'd like to hear your comments. I saw the list of libraries on the json.org site, but it's a fairly big list and the community is usually good at vetting out the contenders from the pretenders
我很想知道。net社区的人都在用什么JSON库?我需要从。net (c#)内部解析/序列化一些JSON对象图到实际的。net类型。我也可以使用我自己的库,但是如果有人使用过一些可靠的库,我想听听你们的意见。我在json.org网站上看到了图书馆的列表,但它是一个相当大的列表,而且社区通常很擅长从冒牌货中筛选竞争者
Any details (pros/cons) of your experience with the library would be incredibly helpful. -- thanks in advance.
任何关于你在图书馆的经历的细节(赞成/反对)都是非常有用的。——谢谢。
7 个解决方案
#1
22
I've used Json.NET with success in the past.
我使用了Json。网与过去的成功。
Example from the site:
网站的例子:
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);
#2
19
There are at least two built into the framework.
框架中至少有两个。
The newer : System.Runtime.Serialization.Json
更新:System.Runtime.Serialization.Json
and the older : System.Web.Script.Serialization
旧的:System.Web.Script.Serialization
I prefer to not have dependencies on 3rd party libraries. I work with JSON every day and have never needed anything more than what already exists in the framework.
我宁愿不依赖第三方库。我每天都在使用JSON,除了框架中已经存在的东西之外,我不需要任何东西。
#3
10
I wrote my own JSON serializer using DataContractJsonSerializer in the System.ServiceModel.Web.dll
assembly [which is a component of WCF included in .NET 3.5 as a standard assembly, and in the .NET 3.5 SP1 Client Profile] (in .NET 4.0 and Silverlight 4, it's been moved to System.Runtime.Serialization.dll
).
我在System.ServiceModel.Web上使用DataContractJsonSerializer编写了自己的JSON序列化器。dll程序集[是. net 3.5中包含的WCF的一个组件,在. net 3.5 SP1客户端配置文件中](在. net 4.0和Silverlight 4中,它被移动到system . runtime . serializ.dll .dll .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;
}
}
}
}
#4
5
You should also try my ServiceStack JsonSerializer - it's the fastest .NET JSON serializer at the moment based on the benchmarks of the leading JSON serializers and supports serializing any POCO Type, DataContracts, Lists/Dictionaries, Interfaces, Inheritance, Late-bound objects including anonymous types, etc.
您还应该尝试我的ServiceStack JsonSerializer——它是目前基于领先的JSON序列化器基准的最快的。net JSON序列化器,并支持序列化任何POCO类型、datacontract、列表/字典、接口、继承、包括匿名类型在内的最新绑定对象等等。
Basic Example:
基本的例子:
Customer customer = new Customer { Name="Joe Bloggs", Age=31 };
string json = customer.ToJson();
Customer fromJson = json.FromJson<Customer>(json);
#5
3
Check out the System.Runtime.Serialization.Json Namespace included with .NET 3.5.
查看System.Runtime.Serialization。. net 3.5包含Json命名空间。
#6
2
I typed "json" into google and the top hit was json.org, which leads to what looks like a good single utility class:
我在谷歌中输入了“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 ("0123456789+-.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);
}
}
}
#7
1
I've used System.Web.Helpers.Json for encoding and decoding. It decodes into a dynamic types, which is a good match for javascript's dynamic data.
我用System.Web.Helpers。Json用于编码和解码。它可以解码成动态类型,这与javascript的动态数据很匹配。
#1
22
I've used Json.NET with success in the past.
我使用了Json。网与过去的成功。
Example from the site:
网站的例子:
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);
#2
19
There are at least two built into the framework.
框架中至少有两个。
The newer : System.Runtime.Serialization.Json
更新:System.Runtime.Serialization.Json
and the older : System.Web.Script.Serialization
旧的:System.Web.Script.Serialization
I prefer to not have dependencies on 3rd party libraries. I work with JSON every day and have never needed anything more than what already exists in the framework.
我宁愿不依赖第三方库。我每天都在使用JSON,除了框架中已经存在的东西之外,我不需要任何东西。
#3
10
I wrote my own JSON serializer using DataContractJsonSerializer in the System.ServiceModel.Web.dll
assembly [which is a component of WCF included in .NET 3.5 as a standard assembly, and in the .NET 3.5 SP1 Client Profile] (in .NET 4.0 and Silverlight 4, it's been moved to System.Runtime.Serialization.dll
).
我在System.ServiceModel.Web上使用DataContractJsonSerializer编写了自己的JSON序列化器。dll程序集[是. net 3.5中包含的WCF的一个组件,在. net 3.5 SP1客户端配置文件中](在. net 4.0和Silverlight 4中,它被移动到system . runtime . serializ.dll .dll .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;
}
}
}
}
#4
5
You should also try my ServiceStack JsonSerializer - it's the fastest .NET JSON serializer at the moment based on the benchmarks of the leading JSON serializers and supports serializing any POCO Type, DataContracts, Lists/Dictionaries, Interfaces, Inheritance, Late-bound objects including anonymous types, etc.
您还应该尝试我的ServiceStack JsonSerializer——它是目前基于领先的JSON序列化器基准的最快的。net JSON序列化器,并支持序列化任何POCO类型、datacontract、列表/字典、接口、继承、包括匿名类型在内的最新绑定对象等等。
Basic Example:
基本的例子:
Customer customer = new Customer { Name="Joe Bloggs", Age=31 };
string json = customer.ToJson();
Customer fromJson = json.FromJson<Customer>(json);
#5
3
Check out the System.Runtime.Serialization.Json Namespace included with .NET 3.5.
查看System.Runtime.Serialization。. net 3.5包含Json命名空间。
#6
2
I typed "json" into google and the top hit was json.org, which leads to what looks like a good single utility class:
我在谷歌中输入了“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 ("0123456789+-.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);
}
}
}
#7
1
I've used System.Web.Helpers.Json for encoding and decoding. It decodes into a dynamic types, which is a good match for javascript's dynamic data.
我用System.Web.Helpers。Json用于编码和解码。它可以解码成动态类型,这与javascript的动态数据很匹配。