前一段时间去一个客户那做支持的时候,看到一哥们使用了MS ajax类库,使用的效果让我觉得很新鲜,在服务器端定义的一些方法,只要加上ajax库的某个属性,则可在client-side中直接进行调用,如果服务器端方法有返回值的话,在客户端还能接收并像使用服务器端对象一般,我之前一直很疑惑,为什么能做到如此,当时看到在服务器端返回一个datatable对象,然后就看到在客户端使用这个datatable对象了,使用的代码和方式就像再写服务器端代码一样,当时很是疑惑,因为自己刚接触web不久,最终没能正面的帮客户解决使用中的一个问题,而是提供了另一种比较笨的方式callback。后来有幸看到一篇介绍JSON的文章,渐渐的思路有点清晰起来,猜想应该是在服务器端将某个对象序列化成JSON,然后在客户端再将JSON实例化成某个对象,为了印证我的思路,google上一搜,果然已经有了很多将对象序列化成JSON的代码,附上codeproject上的一个实现:
http://www.codeproject.com/KB/aspnet/ASPNET_DataTable_to_JSON.aspx
还有人专门从Anthem.net中专门剥离出了这部分代码,这里也一并附上:
public class Converter
{
private static void WriteDataRow(StringBuilder sb, DataRow row)
{
sb.Append("{");
foreach (DataColumn column in row.Table.Columns)
{
sb.AppendFormat("/"{0}/":", column.ColumnName);
WriteValue(sb, row[column]);
sb.Append(",");
}
// Remove the trailing comma.
if (row.Table.Columns.Count > 0)
{
--sb.Length;
}
sb.Append("}");
}
private static void WriteDataSet(StringBuilder sb, DataSet ds)
{
sb.Append("{/"Tables/":{");
foreach (DataTable table in ds.Tables)
{
sb.AppendFormat("/"{0}/":", table.TableName);
WriteDataTable(sb, table);
sb.Append(",");
}
// Remove the trailing comma.
if (ds.Tables.Count > 0)
{
--sb.Length;
}
sb.Append("}}");
}
private static void WriteDataTable(StringBuilder sb, DataTable table)
{
sb.Append("{/"Rows/":[");
foreach (DataRow row in table.Rows)
{
WriteDataRow(sb, row);
sb.Append(",");
}
// Remove the trailing comma.
if (table.Rows.Count > 0)
{
--sb.Length;
}
sb.Append("]}");
}
private static void WriteEnumerable(StringBuilder sb, IEnumerable e)
{
bool hasItems = false;
sb.Append("[");
foreach (object val in e)
{
WriteValue(sb, val);
sb.Append(",");
hasItems = true;
}
// Remove the trailing comma.
if (hasItems)
{
--sb.Length;
}
sb.Append("]");
}
private static void WriteHashtable(StringBuilder sb, Hashtable e)
{
bool hasItems = false;
sb.Append("{");
foreach (string key in e.Keys)
{
sb.AppendFormat("/"{0}/":", key.ToLower());
WriteValue(sb, e[key]);
sb.Append(",");
hasItems = true;
}
// Remove the trailing comma.
if (hasItems)
{
--sb.Length;
}
sb.Append("}");
}
private static void WriteObject(StringBuilder sb, object o)
{
MemberInfo[] members = o.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public);
sb.Append("{");
bool hasMembers = false;
foreach (MemberInfo member in members)
{
bool hasValue = false;
object val = null;
if ((member.MemberType & MemberTypes.Field) == MemberTypes.Field)
{
FieldInfo field = (FieldInfo)member;
val = field.GetValue(o);
hasValue = true;
}
else if ((member.MemberType & MemberTypes.Property) == MemberTypes.Property)
{
PropertyInfo property = (PropertyInfo)member;
if (property.CanRead && property.GetIndexParameters().Length == 0)
{
val = property.GetValue(o, null);
hasValue = true;
}
}
if (hasValue)
{
sb.Append("/"");
sb.Append(member.Name);
sb.Append("/":");
WriteValue(sb, val);
sb.Append(",");
hasMembers = true;
}
}
if (hasMembers)
{
--sb.Length;
}
sb.Append("}");
}
private static void WriteString(StringBuilder sb, string s)
{
sb.Append("/"");
foreach (char c in s)
{
switch (c)
{
case '/"':
sb.Append("///"");
break;
case '//':
sb.Append("");
break;
case '/b':
sb.Append("//b");
break;
case '/f':
sb.Append("//f");
break;
case '/n':
sb.Append("//n");
break;
case '/r':
sb.Append("//r");
break;
case '/t':
sb.Append("//t");
break;
default:
int i = (int)c;
if (i < 32 || i > 127)
{
sb.AppendFormat("//u{0:X04}", i);
}
else
{
sb.Append(c);
}
break;
}
}
sb.Append("/"");
}
public static void WriteValue(StringBuilder sb, object val)
{
if (val == null || val == System.DBNull.Value)
{
sb.Append("null");
}
else if (val is string || val is Guid)
{
WriteString(sb, val.ToString());
}
else if (val is bool)
{
sb.Append(val.ToString().ToLower());
}
else if (val is double ||
val is float ||
val is long ||
val is int ||
val is short ||
val is byte ||
val is decimal)
{
sb.AppendFormat(CultureInfo.InvariantCulture.NumberFormat, "{0}", val);
}
else if (val.GetType().IsEnum)
{
sb.Append((int)val);
}
else if (val is DateTime)
{
sb.Append("new Date(/"");
sb.Append(((DateTime)val).ToString("MMMM, d yyyy HH:mm:ss", new CultureInfo("en-US", false).DateTimeFormat));
sb.Append("/")");
}
else if (val is DataSet)
{
WriteDataSet(sb, val as DataSet);
}
else if (val is DataTable)
{
WriteDataTable(sb, val as DataTable);
}
else if (val is DataRow)
{
WriteDataRow(sb, val as DataRow);
}
else if (val is Hashtable)
{
WriteHashtable(sb, val as Hashtable);
}
else if (val is IEnumerable)
{
WriteEnumerable(sb, val as IEnumerable);
}
else
{
WriteObject(sb, val);
}
}
public static string Convert2Json(object o)
{
StringBuilder sb = new StringBuilder();
WriteValue(sb, o);
return sb.ToString();
}
}
其实ms的ajax library肯定也有相关的类实现这样的功能,Sys.Serialization.JavaScriptSerializer,没错,就是这个家伙了。
因为最近也在玩玩java,对它是越来越有好感了,虽然目前为止用的不多,但有一点体会,学习java更容易接近事物的本质,net下的封装逐渐将人变成ms的组件搬运工了:)
假设我有一个类型Car
function Car(make, model, year, color) {
this.make = make;
this.model = model;
this.year = year;
this.color = color;
}
我生成一个Car对象并将它发送到服务器端
private void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {
String s3 = request.getParameter("car");
try {
JSONObject jsonObj = new JSONObject(s3);
System.out.println(jsonObj.getString("model"));
System.out.println(jsonObj.getInt("year"));
} catch (JSONException e) {
e.printStackTrace();
}
response.getWriter().print("{ /"name/": /"Violet/", /"occupation/": /"character/" }");
}
http://www.codeproject.com/KB/aspnet/ASPNET_DataTable_to_JSON.aspx
还有人专门从Anthem.net中专门剥离出了这部分代码,这里也一并附上:
public class Converter
{
private static void WriteDataRow(StringBuilder sb, DataRow row)
{
sb.Append("{");
foreach (DataColumn column in row.Table.Columns)
{
sb.AppendFormat("/"{0}/":", column.ColumnName);
WriteValue(sb, row[column]);
sb.Append(",");
}
// Remove the trailing comma.
if (row.Table.Columns.Count > 0)
{
--sb.Length;
}
sb.Append("}");
}
private static void WriteDataSet(StringBuilder sb, DataSet ds)
{
sb.Append("{/"Tables/":{");
foreach (DataTable table in ds.Tables)
{
sb.AppendFormat("/"{0}/":", table.TableName);
WriteDataTable(sb, table);
sb.Append(",");
}
// Remove the trailing comma.
if (ds.Tables.Count > 0)
{
--sb.Length;
}
sb.Append("}}");
}
private static void WriteDataTable(StringBuilder sb, DataTable table)
{
sb.Append("{/"Rows/":[");
foreach (DataRow row in table.Rows)
{
WriteDataRow(sb, row);
sb.Append(",");
}
// Remove the trailing comma.
if (table.Rows.Count > 0)
{
--sb.Length;
}
sb.Append("]}");
}
private static void WriteEnumerable(StringBuilder sb, IEnumerable e)
{
bool hasItems = false;
sb.Append("[");
foreach (object val in e)
{
WriteValue(sb, val);
sb.Append(",");
hasItems = true;
}
// Remove the trailing comma.
if (hasItems)
{
--sb.Length;
}
sb.Append("]");
}
private static void WriteHashtable(StringBuilder sb, Hashtable e)
{
bool hasItems = false;
sb.Append("{");
foreach (string key in e.Keys)
{
sb.AppendFormat("/"{0}/":", key.ToLower());
WriteValue(sb, e[key]);
sb.Append(",");
hasItems = true;
}
// Remove the trailing comma.
if (hasItems)
{
--sb.Length;
}
sb.Append("}");
}
private static void WriteObject(StringBuilder sb, object o)
{
MemberInfo[] members = o.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public);
sb.Append("{");
bool hasMembers = false;
foreach (MemberInfo member in members)
{
bool hasValue = false;
object val = null;
if ((member.MemberType & MemberTypes.Field) == MemberTypes.Field)
{
FieldInfo field = (FieldInfo)member;
val = field.GetValue(o);
hasValue = true;
}
else if ((member.MemberType & MemberTypes.Property) == MemberTypes.Property)
{
PropertyInfo property = (PropertyInfo)member;
if (property.CanRead && property.GetIndexParameters().Length == 0)
{
val = property.GetValue(o, null);
hasValue = true;
}
}
if (hasValue)
{
sb.Append("/"");
sb.Append(member.Name);
sb.Append("/":");
WriteValue(sb, val);
sb.Append(",");
hasMembers = true;
}
}
if (hasMembers)
{
--sb.Length;
}
sb.Append("}");
}
private static void WriteString(StringBuilder sb, string s)
{
sb.Append("/"");
foreach (char c in s)
{
switch (c)
{
case '/"':
sb.Append("///"");
break;
case '//':
sb.Append("");
break;
case '/b':
sb.Append("//b");
break;
case '/f':
sb.Append("//f");
break;
case '/n':
sb.Append("//n");
break;
case '/r':
sb.Append("//r");
break;
case '/t':
sb.Append("//t");
break;
default:
int i = (int)c;
if (i < 32 || i > 127)
{
sb.AppendFormat("//u{0:X04}", i);
}
else
{
sb.Append(c);
}
break;
}
}
sb.Append("/"");
}
public static void WriteValue(StringBuilder sb, object val)
{
if (val == null || val == System.DBNull.Value)
{
sb.Append("null");
}
else if (val is string || val is Guid)
{
WriteString(sb, val.ToString());
}
else if (val is bool)
{
sb.Append(val.ToString().ToLower());
}
else if (val is double ||
val is float ||
val is long ||
val is int ||
val is short ||
val is byte ||
val is decimal)
{
sb.AppendFormat(CultureInfo.InvariantCulture.NumberFormat, "{0}", val);
}
else if (val.GetType().IsEnum)
{
sb.Append((int)val);
}
else if (val is DateTime)
{
sb.Append("new Date(/"");
sb.Append(((DateTime)val).ToString("MMMM, d yyyy HH:mm:ss", new CultureInfo("en-US", false).DateTimeFormat));
sb.Append("/")");
}
else if (val is DataSet)
{
WriteDataSet(sb, val as DataSet);
}
else if (val is DataTable)
{
WriteDataTable(sb, val as DataTable);
}
else if (val is DataRow)
{
WriteDataRow(sb, val as DataRow);
}
else if (val is Hashtable)
{
WriteHashtable(sb, val as Hashtable);
}
else if (val is IEnumerable)
{
WriteEnumerable(sb, val as IEnumerable);
}
else
{
WriteObject(sb, val);
}
}
public static string Convert2Json(object o)
{
StringBuilder sb = new StringBuilder();
WriteValue(sb, o);
return sb.ToString();
}
}
其实ms的ajax library肯定也有相关的类实现这样的功能,Sys.Serialization.JavaScriptSerializer,没错,就是这个家伙了。
因为最近也在玩玩java,对它是越来越有好感了,虽然目前为止用的不多,但有一点体会,学习java更容易接近事物的本质,net下的封装逐渐将人变成ms的组件搬运工了:)
假设我有一个类型Car
function Car(make, model, year, color) {
this.make = make;
this.model = model;
this.year = year;
this.color = color;
}
我生成一个Car对象并将它发送到服务器端
- function sendRequest() {
- var carr = new Car("Dodge", "Coronet R/T", 1968, "yellow");
- var pars = "car=" + carr.toJSONString();
- var url = "/MyWebApp/JSONTest1";
- var mailAjax = new Ajax.Request(
- url,
- {
- method: 'get',
- parameters: pars,
- onComplete: jsonResponse
- }
- );
- }
private void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {
String s3 = request.getParameter("car");
try {
JSONObject jsonObj = new JSONObject(s3);
System.out.println(jsonObj.getString("model"));
System.out.println(jsonObj.getInt("year"));
} catch (JSONException e) {
e.printStackTrace();
}
response.getWriter().print("{ /"name/": /"Violet/", /"occupation/": /"character/" }");
}