A DataTable Serializer for ASP.NET AJAX, implements JavaScriptConverter. Note that I did not implement a Deserialize method since I am using this for read only data.
[code:c#]
/// <summary>
/// DataTable to JSON converter
/// </summary>
public class JavaScriptDataTableConverter : JavaScriptConverter {
public override object Deserialize( IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer ) {
throw new NotImplementedException( "Deserialize is not implemented." );
}

public override IDictionary<string, object> Serialize( object obj, JavaScriptSerializer serializer ) {
DataTable dt = obj as DataTable;
Dictionary<string, object> result = new Dictionary<string, object>();

if( dt != null && dt.Rows.Count > 0 ) {
// List for row values
List<object> rowValues = new List<object>();

foreach( DataRow dr in dt.Rows ) {
// Dictionary for col name / col value
Dictionary<string, object> colValues = new Dictionary<string, object>();

foreach( DataColumn dc in dt.Columns ) {
colValues.Add( dc.ColumnName, // col name
( string.Empty == dr[dc].ToString() ) ? null : dr[dc] ); // col value
}

// Add values to row
rowValues.Add( colValues );
}

// Add rows to serialized object
result["rows"] = rowValues;
}

return result;
}

public override IEnumerable<Type> SupportedTypes {
//Define the DataTable as a supported type.
get {
return new System.Collections.ObjectModel.ReadOnlyCollection<Type>(
new List<Type>(
new Type[] { typeof( DataTable ) }
)
);
}
}
}

/// <summary>
/// DataTable to JSON converter
/// </summary>
public class JavaScriptDataTableConverter : JavaScriptConverter {
public override object Deserialize( IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer ) {
throw new NotImplementedException( "Deserialize is not implemented." );
} 
public override IDictionary<string, object> Serialize( object obj, JavaScriptSerializer serializer ) {
DataTable dt = obj as DataTable;
Dictionary<string, object> result = new Dictionary<string, object>(); 
if( dt != null && dt.Rows.Count > 0 ) {
// List for row values
List<object> rowValues = new List<object>(); 
foreach( DataRow dr in dt.Rows ) {
// Dictionary for col name / col value
Dictionary<string, object> colValues = new Dictionary<string, object>(); 
foreach( DataColumn dc in dt.Columns ) {
colValues.Add( dc.ColumnName, // col name
( string.Empty == dr[dc].ToString() ) ? null : dr[dc] ); // col value
} 
// Add values to row
rowValues.Add( colValues );
} 
// Add rows to serialized object
result["rows"] = rowValues;
} 
return result;
} 
public override IEnumerable<Type> SupportedTypes {
//Define the DataTable as a supported type.
get {
return new System.Collections.ObjectModel.ReadOnlyCollection<Type>(
new List<Type>(
new Type[] { typeof( DataTable ) }
)
);
}
}
}

[/code]
And how do you implement this? In a web service...
[code:c#]
using System.Web.Script.Serialization;

//

[WebMethod()]
[ScriptMethod( ResponseFormat = ResponseFormat.Json )]
public string TestJS( int Id ) {
JavaScriptSerializer toJSON = new JavaScriptSerializer();
toJSON.RegisterConverters( new JavaScriptConverter[] { new JavaScriptDataTableConverter() } );

DataTable dt = new Query( Log.Schema )
.WHERE( Log.Columns.ID, Id )
.ExecuteDataSet().Tables[0];

return toJSON.Serialize( dt );
}
[/code]
using System.Web.Script.Serialization; 
//

[WebMethod()]
[ScriptMethod( ResponseFormat = ResponseFormat.Json )]
public string TestJS( int Id ) {
JavaScriptSerializer toJSON = new JavaScriptSerializer();
toJSON.RegisterConverters( new JavaScriptConverter[] { new JavaScriptDataTableConverter() } ); 
DataTable dt = new Query( Log.Schema )
.WHERE( Log.Columns.ID, Id )
.ExecuteDataSet().Tables[0]; 
return toJSON.Serialize( dt );
}
[/code]
That's all there is to it! Just deserialize to an object on the client-side and you're good to go!
Side Note: There is a DataTable serializer from Microsoft in the ASP.NET Futures package.
posted @ 2007-11-22 12:19 客家网络 阅读(473) 评论(0) 编辑


