using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using System.Data;

public class JsonHelper
{
    #region  序列化和反序列化
    // 序列化
    public static string JsonSerializer<T>(T t)
    {
        // 使用 DataContractJsonSerializer 将 T 对象序列化为内存流。 
        DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream();
        // 使用 WriteObject 方法将 JSON 数据写入到流中。 
        jsonSerializer.WriteObject(ms, t);
        // 流转字符串
        string jsonString = Encoding.UTF8.GetString(ms.ToArray());
        ms.Close();
        //替换Json的Date字符串  
        string p = @"\\/Date\((\d+)\+\d+\)\\/";
        MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
        Regex reg = new Regex(p);
        jsonString = reg.Replace(jsonString, matchEvaluator);
        return jsonString;
    }
    public static T JsonDeserialize<T>(string jsonString)
    {
        //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式  
        string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
        MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
        Regex reg = new Regex(p);
        jsonString = reg.Replace(jsonString, matchEvaluator);
        DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(T));
        // 字符串转流
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        // 通过使用 DataContractJsonSerializer 的 ReadObject 方法，将 JSON 编码数据反序列化为T 
        T obj = (T)jsonSerializer.ReadObject(ms);
        return obj;
    }
    public static string ConvertJsonDateToDateString(Match match)
    {
        string result = string.Empty;
        DateTime dateTime = new DateTime(1970, 1, 1);
        dateTime = dateTime.AddMilliseconds(long.Parse(match.Groups[1].Value));
        dateTime = dateTime.ToLocalTime();
        result = dateTime.ToString("yyyy-MM-dd HH:mm:ss");
        return result;
    }
    private static string ConvertDateStringToJsonDate(Match m)
    {
        string result = string.Empty;
        DateTime dt = DateTime.Parse(m.Groups[0].Value);
        dt = dt.ToUniversalTime();
        TimeSpan ts = dt - DateTime.Parse("1970-01-01");
        result = string.Format("\\/Date({0}+0800)\\/", ts.TotalMilliseconds);
        return result;
    }
    #endregion

    // 对象转换为Json
    public static string ObjectToJson(object obj)
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        try
        {
            return js.Serialize(obj);
        }
        catch (Exception exception)
        {

            throw new Exception(exception.Message);
        }
    }
    // 数据表转化为集合
    public static List<Dictionary<string, object>> DataTableToList(DataTable dt)
    {
        List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
        foreach (DataRow dataRow in dt.Rows)
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            foreach (DataColumn dc in dt.Columns)
            {
                dic.Add(dc.ColumnName, dataRow[dc.ColumnName]);
            }
            list.Add(dic);
        }
        return list;
    }
    // 表转换为Json
    public static string DataTableToJson(DataTable dt)
    {
        return ObjectToJson(DataTableToList(dt));
    }
    /// <summary>
    /// 将DataTable中的数据转换成JSON格式
    /// </summary>
    /// <param name="dt">数据源DataTable</param>
    /// <param name="displayCount">是否输出数据总条数</param>
    /// <param name="totalcount">JSON中显示的数据总条数</param>
    /// <returns></returns>
    public static string CreateJsonParameters(DataTable dt, bool displayCount, int totalcount)
    {
        StringBuilder JsonString = new StringBuilder();
        //Exception Handling        

        if (dt != null)
        {
            JsonString.Append("{ ");
            JsonString.Append("\"rows\":[ ");
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                JsonString.Append("{ ");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    if (j < dt.Columns.Count - 1)
                    {
                        //if (dt.Rows[i][j] == DBNull.Value) continue;
                        if (dt.Columns[j].DataType == typeof(bool))
                        {
                            JsonString.Append("\"JSON_" + dt.Columns[j].ColumnName.ToLower() + "\":" +
                                              dt.Rows[i][j].ToString().ToLower() + ",");
                        }
                        else if (dt.Columns[j].DataType == typeof(string))
                        {
                            JsonString.Append("\"JSON_" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" +
                                              dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\",");
                        }
                        else
                        {
                            JsonString.Append("\"JSON_" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" + dt.Rows[i][j] + "\",");
                        }
                    }
                    else if (j == dt.Columns.Count - 1)
                    {
                        //if (dt.Rows[i][j] == DBNull.Value) continue;
                        if (dt.Columns[j].DataType == typeof(bool))
                        {
                            JsonString.Append("\"JSON_" + dt.Columns[j].ColumnName.ToLower() + "\":" +
                                              dt.Rows[i][j].ToString().ToLower());
                        }
                        else if (dt.Columns[j].DataType == typeof(string))
                        {
                            JsonString.Append("\"JSON_" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" +
                                              dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\"");
                        }
                        else
                        {
                            JsonString.Append("\"JSON_" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" + dt.Rows[i][j] + "\"");
                        }
                    }
                }
                /*end Of String*/
                if (i == dt.Rows.Count - 1)
                {
                    JsonString.Append("} ");
                }
                else
                {
                    JsonString.Append("}, ");
                }
            }
            JsonString.Append("]");

            if (displayCount)
            {
                JsonString.Append(",");

                JsonString.Append("\"total\":");
                JsonString.Append(totalcount);
            }

            JsonString.Append("}");
            return JsonString.ToString().Replace("\n", "");
        }
        else
        {
            return null;
        }
    }
    StringBuilder result = new StringBuilder();
    StringBuilder sb = new StringBuilder();
    /// <summary>
    /// 根据DataTable生成EasyUI Tree Json树结构
    /// </summary>
    /// <param name="tabel">数据源</param>
    /// <param name="idCol">ID列</param>
    /// <param name="txtCol">Text列</param>
    /// <param name="url">节点Url</param>
    /// <param name="rela">关系字段</param>
    /// <param name="pId">父ID</param>
    public string GetTreeJsonByTable(DataTable tabel, string idCol, string txtCol, string url, string rela, object pId)
    {
        result.Append(sb.ToString());
        sb.Clear();
        if (tabel.Rows.Count > 0)
        {
            sb.Append("[");
            string filer = string.Format("{0}='{1}'", rela, pId);
            DataRow[] rows = tabel.Select(filer);
            if (rows.Length > 0)
            {
                foreach (DataRow row in rows)
                {
                    sb.Append("{\"id\":\"" + row[idCol] + "\",\"text\":\"" + row[txtCol] + "\",\"attributes\":\"" + row[url] + "\",\"state\":\"open\"");
                    if (tabel.Select(string.Format("{0}='{1}'", rela, row[idCol])).Length > 0)
                    {
                        sb.Append(",\"children\":");
                        GetTreeJsonByTable(tabel, idCol, txtCol, url, rela, row[idCol]);
                        result.Append(sb.ToString());
                        sb.Clear();
                    }
                    result.Append(sb.ToString());
                    sb.Clear();
                    sb.Append("},");
                }
                sb = sb.Remove(sb.Length - 1, 1);
            }
            sb.Append("]");
            result.Append(sb.ToString());
            sb.Clear();
        }
        return result.ToString();
    }
}