📄 javascriptserializer.cs
字号:
/*
* MS 06-04-03 fixed Decimal value, now using double instead
* MS 06-04-04 added enum as integer instead of returning a class
*
*
*
*/
using System;
using System.Text;
using System.Reflection;
namespace AjaxPro
{
/// <summary>
/// Provides methods for serializing .NET objects to Java Script Object Notation (JSON).
/// </summary>
public class JavaScriptSerializer
{
/// <summary>
/// Converts a .NET object into a JSON string.
/// </summary>
/// <param name="o">The object to convert.</param>
/// <returns>Returns a JSON string.</returns>
/// <example>
/// using System;
/// using AjaxPro;
///
/// namespace Demo
/// {
/// public class WebForm1 : System.Web.UI.Page
/// {
/// private void Page_Load(object sender, System.EventArgs e)
/// {
/// DateTime serverTime = DateTime.Now;
/// string json = JavaScriptSerializer.Serialize(serverTime);
///
/// // json = "new Date(...)";
/// }
/// }
/// }
/// </example>
public static string Serialize(object o)
{
JavaScriptSerializer js = new JavaScriptSerializer();
return js.SerializeInternal(o);
}
/// <summary>
/// Converts a string into a JSON string.
/// </summary>
/// <param name="s">The string to convert.</param>
/// <returns>Returns a JSON string.</returns>
public static string SerializeString(string s)
{
JavaScriptSerializer js = new JavaScriptSerializer();
return js.SerializeInternal(s);
}
#region Internal Methods
internal string SerializeInternal(object o)
{
StringBuilder sb = new StringBuilder();
this.SerializeValue(o, sb);
return sb.ToString();
}
internal void SerializeString(string s, StringBuilder sb)
{
sb.Append("\"");
sb.Append(JavaScriptUtil.QuoteString(s));
sb.Append("\"");
}
internal void SerializeDecimal(Decimal d, StringBuilder sb)
{
// this.SerializeValue(Decimal.GetBits(d), sb);
// The following code is not correct, but while JavaScript cannot
// handle the decimal value correct we are using double instead.
this.SerializePrimitive((double)d, sb);
}
internal void SerializeBoolean(bool b, StringBuilder sb)
{
sb.Append((b ? "true" : "false"));
}
internal void SerializePrimitive(object o, StringBuilder sb)
{
if(o is char || o is byte || o is sbyte)
{
sb.Append(o.ToString());
return;
}
if(o is float && ((float)o) == float.NaN)
{
throw new ArgumentException("object must be a valid number (float.NaN)", "number");
}
if(o is double && ((double)o) == double.NaN)
{
throw new ArgumentException("object must be a valid number (double.NaN)", "number");
}
// Shave off trailing zeros and decimal point, if possible
string s = o.ToString().ToLower().Replace(System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator, ".");
if(s.IndexOf('e') < 0 && s.IndexOf('.') > 0)
{
while(s.EndsWith("0"))
{
s.Substring(0,s.Length-1);
}
if (s.EndsWith("."))
{
s.Substring(0,s.Length-1);
}
}
sb.Append(s);
}
internal void SerializeArray(Array a, StringBuilder sb)
{
bool b = true;
sb.Append("[");
foreach(object o in a)
{
if(b){ b = false; }
else{ sb.Append(","); }
this.SerializeValue(o, sb);
}
sb.Append("]");
}
internal void SerializeCustomObject(object o, StringBuilder sb)
{
AjaxNonSerializableAttribute[] nsa = (AjaxNonSerializableAttribute[])o.GetType().GetCustomAttributes(typeof(AjaxNonSerializableAttribute), true);
bool b = false;
sb.Append('{');
sb.Append("\"__type\":");
this.SerializeString(o.GetType().AssemblyQualifiedName, sb);
FieldInfo[] fields = o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
for(int i=0; i<fields.Length; i++)
{
FieldInfo fi = fields[i];
if((nsa.Length > 0 && fi.GetCustomAttributes(typeof(AjaxPropertyAttribute), true).Length > 0) ||
(nsa.Length == 0 && fi.GetCustomAttributes(typeof(AjaxNonSerializableAttribute), true).Length == 0))
{
if(b){ b = false; }
else{ sb.Append(','); }
this.SerializeString(fi.Name, sb);
sb.Append(':');
this.SerializeValue(fi.GetValue(o), sb);
}
}
b = false;
PropertyInfo[] properties = o.GetType().GetProperties(BindingFlags.GetProperty | (BindingFlags.Public | BindingFlags.Instance));
for(int i=0; i<properties.Length; i++)
{
PropertyInfo prop = properties[i];
MethodInfo mi = prop.GetGetMethod();
if (mi.GetParameters().Length <= 0)
{
if((nsa.Length > 0 && mi.GetCustomAttributes(typeof(AjaxPropertyAttribute), true).Length > 0) ||
(nsa.Length == 0 && mi.GetCustomAttributes(typeof(AjaxNonSerializableAttribute), true).Length == 0))
{
if(b){ b = false; }
else{ sb.Append(","); }
this.SerializeString(prop.Name, sb);
sb.Append(':');
this.SerializeValue(mi.Invoke(o, null), sb);
}
}
}
sb.Append('}');
}
internal void SerializeValue(object o, StringBuilder sb)
{
if(o == null || o is System.DBNull)
{
sb.Append("null");
}
else if(o is string)
{
this.SerializeString((string)o, sb);
}
else if(o is char)
{
this.SerializeString(o.ToString(), sb);
}
else if(o is bool)
{
this.SerializeBoolean((bool)o, sb);
}
#if(NET20)
//else if (o is Nullable)
//{
//}
#endif
else if (o.GetType().IsPrimitive)
{
this.SerializePrimitive(o, sb);
}
else if (o.GetType().IsEnum)
{
this.SerializePrimitive((int)o, sb);
}
else if (o is Guid)
{
this.SerializeString(o.ToString(), sb);
}
else if (o is Decimal)
{
this.SerializeDecimal((Decimal)o, sb);
// sb.Append(o.ToString());
}
else if (o is Exception)
{
Exception ex = (Exception)o;
sb.Append("null; r.error = {\"Message\":");
this.SerializeString(ex.Message, sb);
sb.Append(",\"Type\":");
this.SerializeString(o.GetType().FullName, sb);
if (AjaxPro.Utility.Settings.DebugEnabled)
{
sb.Append(",\"Stack\":");
this.SerializeString(ex.StackTrace, sb);
sb.Append(",\"TargetSite\":");
this.SerializeString(ex.TargetSite.ToString(), sb);
sb.Append(",\"Source\":");
this.SerializeString(ex.Source, sb);
}
sb.Append("}");
}
else
{
JavaScriptConverterAttribute[] attr = (JavaScriptConverterAttribute[])o.GetType().GetCustomAttributes(typeof(JavaScriptConverterAttribute), false);
if (attr.Length > 0)
{
sb.Append(attr[0].Converter.Serialize(o));
return;
}
IJavaScriptConverter c = JavaScriptConverter.GetSerializableConverter(o.GetType());
if (c != null)
{
sb.Append(c.Serialize(o));
return;
}
if (o.GetType().IsArray)
{
this.SerializeArray((Array)o, sb);
}
else
{
this.SerializeCustomObject(o, sb);
}
}
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -