好一段時間沒有寫文章,最近剛搬家,家裏還沒裝上網絡,代碼農沒有網絡是蠻恐怖的一事件。
願歸正傳今天我想說的自定義json與DataTable相互轉換。相信大家都有看過微軟的.NET中實現JSON的API 的相應方法吧。首先我們看看 Newtonsoft.Json.JsonConvert 是怎麼完成的:
DataTable table = new DataTable();
table.Columns.Add("id");
table.Columns.Add("name");
table.Columns.Add("url");
table.Rows.Add("1", "zhengdjin", "http://blog.csdn.net/zhengdjin");
table.Rows.Add("2", "生活信息網", "http://www.naoqiu.com");
//Newtonsoft.Json api:
//序列化
string api_s= Newtonsoft.Json.JsonConvert.SerializeObject(table);
Console.WriteLine(api_s);
//反序列化
DataTable api_Table = Newtonsoft.Json.JsonConvert.DeserializeObject(api_s, typeof(DataTable)) as DataTable;
Console.ReadLine();
實現的方式相當簡單,微軟都幫我處理掉那些繁雜的操作,那我們來還原將DataTable轉換爲Json格式的情景:
我爲了做更多的擴展,首先創建一個json基類代碼如下:
/// <summary>
/// json基類
/// </summary>
public abstract class IJson<T>
{
/// <summary>
/// 行信息區域塊表示方式
/// </summary>
private string _rowInfo = "{}";
/// <summary>
/// 行分割字符
/// </summary>
private char _rowSp = ',';
/// <summary>
/// 列分割字符
/// </summary>
private char _columnSp = ',';
/// <summary>
/// 行分割字符
/// </summary>
public char RowSplit {
get { return _rowSp; }
set { _rowSp = value; }
}
/// <summary>
/// 列分割字符
/// </summary>
public char ColumnSplit {
get { return _columnSp; }
set { _columnSp = value; }
}
/// <summary>
/// 行信息區域塊表示方式
/// </summary>
public string RowInfo
{
get { return _rowInfo; }
set { _rowInfo = value; }
}
/// <summary>
/// 默認json轉化參數格式
/// </summary>
public IJson() : this(',', ',', "{}") { }
public IJson(char rSplit, char cSplit, string rInfo)
{
this._rowSp=rSplit;
this._columnSp = cSplit;
this._rowInfo = rInfo;
}
/// <summary>
/// 轉化爲json對象
/// </summary>
/// <typeparam name="T">對象類型</typeparam>
/// <param name="t">參數</param>
/// <returns></returns>
public abstract string toJson<T>(T t);
/// <summary>
/// jsaon轉化對象
/// </summary>
/// <param name="json">jsaon字符</param>
/// <returns>對象</returns>
public abstract T toObject(string json);
}
接下來定義一個JsontoDataTable 繼承json基類,然後實現 toJson<T>(T t) 將dataTable轉換爲json
/// <summary>
/// dataTable轉化爲json對象
/// </summary>
/// <typeparam name="T">參數類型</typeparam>
/// <param name="t">參數</param>
/// <returns></returns>
public override string toJson<T>(T t)
{
DataTable table = t as DataTable;
if (table == null) return "";
if (RowInfo.Length != 2) throw new NotImplementedException("行信息區域塊表示方式格式不正確");
StringBuilder jsonBuilder = new StringBuilder();
jsonBuilder.Append(table.TableName+":[");
string head = "";
int i = 0;
foreach (DataColumn dc in table.Columns){
head += dc.ColumnName + ":" + (dc.DataType == typeof(int) || dc.DataType == typeof(decimal) ?
"{" + i++.ToString() + "}" : "\"{" + i++.ToString() + "}\"") + ColumnSplit.ToString();
}
head = head.TrimEnd(ColumnSplit);
foreach (DataRow dr in table.Rows){
jsonBuilder.Append(RowInfo[0].ToString());
jsonBuilder.AppendFormat(head, dr.ItemArray.ToArraybySpecial());
jsonBuilder.Append(RowInfo[1].ToString() + RowSplit.ToString());
}
return jsonBuilder.ToString().Trim(RowSplit) + "]";
}
到這裏已經完成了DataTable轉換爲json ,現在還差個將json轉化爲DataTable,這個方法相對難度比DataTable轉換json稍微。實現這個方法過程中我們得使用正則表達式來獲取數據(可參考asp.net如何加快頁面加載(三)——淺談正則應用)。
/// <summary>
/// json轉化爲DataTable
/// </summary>
/// <param name="json">json變量</param>
/// <returns>DataTable</returns>
public override DataTable toObject(string json)
{
string pattern_row = @"(" + RowInfo[0] + "(.|\n)*?(" + RowInfo[1] + RowSplit +
@")|" + RowInfo[0] + "(.|\n)*?(" + RowInfo[1] + @"\]))";
//獲取行記錄
MatchCollection matches = Regex.Matches(json, pattern_row);
if (matches.Count == 0) return null;
//獲取列名
MatchCollection matches_columns = Regex.Matches(matches[0].Value, "(?<=[" + RowInfo[0].ToString() + ColumnSplit.ToString() + @"])[^\:]+");
DataTable table = new DataTable();
//綁定列名
foreach (Match m in matches_columns) {
table.Columns.Add(m.Value);
}
//綁定數據
DataRow dr;
string value;
foreach (Match m in matches) {
dr = table.NewRow();
foreach (Match mc in matches_columns) {
value = Regex.Match(m.Value, "(?<=[" + RowInfo[0].ToString() + ColumnSplit.ToString() + "]+" + mc.Value + @"\:)[\d\.]+").Value;
if (value == "") {
value = Regex.Match(m.Value, "(?<=[" + RowInfo[0].ToString() + ColumnSplit.ToString() + "]+" +
mc.Value + @"\:\"")(.|\n)*?\""[" + ColumnSplit.ToString() + RowInfo[1].ToString() + "]").Value;
}
dr[mc.Value] = Regex.Replace(value, "\"[" + ColumnSplit.ToString() + RowInfo[1].ToString() + "]", "").toDesSpecial();
}
table.Rows.Add(dr);
}
return table;
}
源碼下載地址:Json與DataTable互轉
總結:微軟給了我們很大的方法,但同時也弱化我們的能力,其實我們只要掌握好基礎知識我們也可以寫出很漂亮的第三方控件,當然這個需要多去實踐多提高(我也是菜鳥)。