C#處理JSON數據


   每次寫博客,第一句話都是這樣的:程序員很苦逼,除了會寫程序,還得會寫博客!當然,希望將來的一天,某位老板看到此博客,給你的程序員職工加點薪資吧!因為程序員的世界除了苦逼就是沉默。我眼中的程序員大多都不愛說話,默默承受着編程的巨大壓力,除了技術上的交流外,他們不願意也不擅長和別人交流,更不樂意任何人走進他們的內心!

   最近悟出來一個道理,在這兒分享給大家:學歷代表你的過去,能力代表你的現在,學習代表你的將來。我們都知道計算機技術發展日新月異,速度驚人的快,你我稍不留神,就會被慢慢淘汰!因此:每日不間斷的學習是避免被淘汰的不二法寶。

   當然,題外話說多了,咱進入正題!

引言
   隨着近年來Android和IOS的流行,越來越多的項目需要處理JSON格式數據,因此:學習JSON相關知識成為了程序員必不可少的一門學術。
   本文以C#語言,針對JSON入手,簡要探討下JSON數據的處理。
誤區
   1、很多類型數據都可以轉化為JSON,譬如:List集合轉化為Json、DataTable轉化為Json、XML轉化為Json等
   2、但是如果反過來轉化是否可以呢?譬如:JSON字符串轉為DataTable,轉為XML,轉為LIST等?
   在此:我給的答案是(1)中轉化不會出現問題,(2)中轉化就不一定完全正確了。究其原因,是因為JSON格式多種多樣,其他數據類型則對結構有所要求!
   例如:DataTable表結構,由列和行組成,稍微復雜的JSON串轉化為DataTable就會出錯。
在此分享一個JSON轉為DataTable的方法,大家自行實驗,而實驗的結果是運行拋出異常,運行報錯。代碼如下:
protected void Page_Load(object sender, EventArgs e)
        {
            string s = @"{'calledList':[{'duration':0,'id':1,'isCalled':true,'isDel':false,'lDate':1423300697418,'name':'楊秀英','number':'13087237088'},{'duration':0,'id':3,'isCalled':true,'isDel':false,'lDate':1473300711441,'name':'付五愛','number':'15898579759'},{'duration':0,'id':4,'isCalled':true,'isDel':false,'lDate':1473301518397,'name':'梁清華','number':'12467320223'},{'duration':0,'id':5,'isCalled':true,'isDel':false,'lDate':1423301571910,'name':'莫春梅','number':'13273209401'}],'counterid':'A-HN-CS-0731-CT023'}";
            DataTable dt = JsonToDataTable(s);
        }
        
        /// <summary>
        /// 將json轉換為DataTable
        /// </summary>
        /// <param name="strJson">得到的json 注意:對JSON的格式有要求  否則異常</param>
        /// <returns></returns>
        public  DataTable JsonToDataTable(string strJson)
        {
            //轉換json格式
            strJson = strJson.Replace(",\"", "*\"").Replace("\":", "\"#").ToString();
            //取出表名   
            var rg = new Regex(@"(?<={)[^:]+(?=:\[)", RegexOptions.IgnoreCase);
            string strName = rg.Match(strJson).Value;
            DataTable tb = null;
            //去除表名   
            strJson = strJson.Substring(strJson.IndexOf("[") + 1);
            strJson = strJson.Substring(0, strJson.IndexOf("]"));

            //獲取數據   
            rg = new Regex(@"(?<={)[^}]+(?=})");
            MatchCollection mc = rg.Matches(strJson);
            for (int i = 0; i < mc.Count; i++)
            {
                string strRow = mc[i].Value;
                string[] strRows = strRow.Split('*');

                //創建表   
                if (tb == null)
                {
                    tb = new DataTable();
                    tb.TableName = strName;
                    foreach (string str in strRows)
                    {
                        var dc = new DataColumn();
                        string[] strCell = str.Split('#');

                        if (strCell[0].Substring(0, 1) == "\"")
                        {
                            int a = strCell[0].Length;
                            dc.ColumnName = strCell[0].Substring(1, a - 2);
                        }
                        else
                        {
                            dc.ColumnName = strCell[0];
                        }
                        tb.Columns.Add(dc);
                    }
                    tb.AcceptChanges();
                }

                //增加內容   
                DataRow dr = tb.NewRow();
                for (int r = 0; r < strRows.Length; r++)
                {
                    dr[r] = strRows[r].Split('#')[1].Trim().Replace("", ",").Replace("", ":").Replace("\"", "");
                }
                tb.Rows.Add(dr);
                tb.AcceptChanges();
            }

            return tb;
        }

   由上實例可知:字符串s的結構要比單純的DataTable復雜多了,因此:要想將字符串s轉為DataTable是行不通的。

   那么,我們應當怎樣轉化JSON呢?在這里給大家介紹一個通用的方法,如下:

   不管多么復雜的JSON串,其結構都是有規律可循的,上述中的s字符串無非是由:calledlist集合和屬性counterid組成,因此,我們可根據分析的JSON結構,創建如下相關類:

 public class callBackList
    {
        public string counterid { get; set; }
        public List<calledList> calledList { get; set; }
    }

    public class calledList
    {
        public int duration { get; set; }
        public int id { get; set; }
        public bool isCalled { get; set; }
        public bool isDel { get; set; }
        public long lDate { get; set; }
        public string name { get; set; }
        public string number { get; set; }
    }

在此:會用到一個通用的方法如下:

  public  T JsonDeserialize<T>(string jsonString)
        {
            return JsonConvert.DeserializeObject<T>(jsonString);
        }

調用實例如下:

protected void Page_Load(object sender, EventArgs e)
        {
            string s = @"{'calledList':[{'duration':0,'id':1,'isCalled':true,'isDel':false,'lDate':1473300697418,'name':'楊秀英','number':'13087237088'},{'duration':0,'id':3,'isCalled':true,'isDel':false,'lDate':1473300711441,'name':'付五愛','number':'15898579759'},{'duration':0,'id':4,'isCalled':true,'isDel':false,'lDate':1473301518397,'name':'梁清華','number':'13467320223'},{'duration':0,'id':5,'isCalled':true,'isDel':false,'lDate':1473301571910,'name':'莫春梅','number':'13873209401'}],'counterid':'A-HN-CS-0731-CT023'}";
            callBackList O = JsonDeserialize<callBackList>(s);
            var Ary = O.calledList;
            string counterId = O.counterid;
            foreach (var A in Ary)
            {
                Response.Write(A.name);
            }
        }

小虎斑們可以自行運行,在此不作過多解釋。

剛才上文中提到:其他類型轉為JSON都是行的通的,JSON轉其他類型不一定行的通,除非JSON結構和所要轉為的數據類型一致,否則就會轉化出錯。

那么,我們如何將其他類型轉為JSON字符串呢?

在此:首先貼出一個通用的方法如下:

public class JsonHelper
    {
        public static string JsonSerializer<T>(T t)
        {

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            MemoryStream ms = new MemoryStream();
            ser.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)
        {
            return JsonConvert.DeserializeObject<T>(jsonString);
        }

        /// <summary>
        /// 將Json序列化的時間由/Date(1294499956278+0800)轉為字符串
        /// </summary>
        private static string ConvertJsonDateToDateString(Match m)
        {

            string result = string.Empty;

            DateTime dt = new DateTime(1970, 1, 1);

            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));

            dt = dt.ToLocalTime();

            result = dt.ToString("yyyy-MM-dd HH:mm:ss");

            return result;

        }

        /// <summary>

        /// 將時間字符串轉為Json時間

        /// </summary>

        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;

        }
    }

上述方法:JsonSerializer<T>(T t)中的T就是通用類型,可以為DataTable    XML   OBJECT等

至於其他方法,都是針對專門的類型就行構造的,如下

  public class JsonHelper
    {

        #region List轉化為Json
        /// <summary>
        /// List轉成json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="jsonName"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static string ListToJson<T>(IList<T> list, string jsonName)
        {
            StringBuilder Json = new StringBuilder();
            if (string.IsNullOrEmpty(jsonName))
                jsonName = list[0].GetType().Name;
            Json.Append("{\"" + jsonName + "\":[");
            if (list.Count > 0)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    T obj = Activator.CreateInstance<T>();
                    PropertyInfo[] pi = obj.GetType().GetProperties();
                    Json.Append("{");
                    for (int j = 0; j < pi.Length; j++)
                    {
                        Type type = pi[j].GetValue(list[i], null).GetType();
                        Json.Append("\"" + pi[j].Name.ToString() + "\":" + StringFormat(pi[j].GetValue(list[i], null).ToString(), type));
                        if (j < pi.Length - 1)
                        {
                            Json.Append(",");
                        }
                    }
                    Json.Append("}");
                    if (i < list.Count - 1)
                    {
                        Json.Append(",");
                    }
                }
            }
            Json.Append("]}");
            return Json.ToString();
        }
        /// <summary>
        /// List轉成json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static string ListToJson<T>(IList<T> list)
        {
            object obj = list[0];
            return ListToJson<T>(list, obj.GetType().Name);
        }
        #endregion

        #region 對象轉化為Json
        /// <summary>
        /// 對象轉換為Json字符串
        /// </summary>
        /// <param name="jsonObject">對象</param>
        /// <returns>Json字符串</returns>
        public static string ToJson(object jsonObject)
        {
            string jsonString = "{";
            PropertyInfo[] propertyInfo = jsonObject.GetType().GetProperties();
            for (int i = 0; i < propertyInfo.Length; i++)
            {
                object objectValue = propertyInfo[i].GetGetMethod().Invoke(jsonObject, null);
                string value = string.Empty;
                if (objectValue is DateTime || objectValue is Guid || objectValue is TimeSpan)
                {
                    value = "'" + objectValue.ToString() + "'";
                }
                else if (objectValue is string)
                {
                    value = "'" + ToJson(objectValue.ToString()) + "'";
                }
                else if (objectValue is IEnumerable)
                {
                    value = ToJson((IEnumerable)objectValue);
                }
                else
                {
                    value = ToJson(objectValue.ToString());
                }
                jsonString += "\"" + ToJson(propertyInfo[i].Name) + "\":" + value + ",";
            }
            jsonString.Remove(jsonString.Length - 1, jsonString.Length);
            return jsonString + "}";
        }
        #endregion

        #region 對象集合轉化為Json
        /// <summary>
        /// 對象集合轉換Json
        /// </summary>
        /// <param name="array">集合對象</param>
        /// <returns>Json字符串</returns>
        public static string ToJson(IEnumerable array)
        {
            string jsonString = "[";
            foreach (object item in array)
            {
                jsonString += ToJson(item) + ",";
            }
            jsonString.Remove(jsonString.Length - 1, jsonString.Length);
            return jsonString + "]";
        }
        /// <summary>
        /// 普通集合轉換Json
        /// </summary>
        /// <param name="array">集合對象</param>
        /// <returns>Json字符串</returns>
        public static string ToArrayString(IEnumerable array)
        {
            string jsonString = "[";
            foreach (object item in array)
            {
                jsonString = ToJson(item.ToString()) + ",";
            }
            jsonString.Remove(jsonString.Length - 1, jsonString.Length);
            return jsonString + "]";
        }
        #endregion

        #region DataTable轉化為Json
        /// <summary>
        /// Datatable轉換為Json
        /// </summary>
        /// <param name="table">Datatable對象</param>
        /// <returns>Json字符串</returns>
        public static string ToJson(DataTable dt)
        {
            StringBuilder jsonString = new StringBuilder();

            if (dt.Rows.Count == 0)
            {
                jsonString.Append("[{}]");
                return jsonString.ToString();
            }

            jsonString.Append("[");
            DataRowCollection drc = dt.Rows;
            for (int i = 0; i < drc.Count; i++)
            {
                jsonString.Append("{");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    string strKey = dt.Columns[j].ColumnName;
                    string strValue = drc[i][j].ToString();
                    Type type = dt.Columns[j].DataType;
                    jsonString.Append("\"" + strKey + "\":");
                    strValue = StringFormat(strValue, type);
                    if (j < dt.Columns.Count - 1)
                    {
                        jsonString.Append(strValue + ",");
                    }
                    else
                    {
                        jsonString.Append(strValue);
                    }
                }
                jsonString.Append("},");
            }
            jsonString.Remove(jsonString.Length - 1, 1);
            jsonString.Append("]");
            return jsonString.ToString();
        }
        /// <summary>
        /// DataTable轉成Json
        /// </summary>
        /// <param name="jsonName"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToJson(DataTable dt, string jsonName)
        {
            StringBuilder Json = new StringBuilder();
            if (string.IsNullOrEmpty(jsonName))
                jsonName = dt.TableName;
            Json.Append("{\"" + jsonName + "\":[");
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    Json.Append("{");
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        Type type = dt.Rows[i][j].GetType();
                        Json.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + StringFormat(dt.Rows[i][j].ToString(), type));
                        if (j < dt.Columns.Count - 1)
                        {
                            Json.Append(",");
                        }
                    }
                    Json.Append("}");
                    if (i < dt.Rows.Count - 1)
                    {
                        Json.Append(",");
                    }
                }
            }
            Json.Append("]}");
            return Json.ToString();
        }
        #endregion

        #region DataReader轉換為Json
        /// <summary>
        /// DataReader轉換為Json
        /// </summary>
        /// <param name="dataReader">DataReader對象</param>
        /// <returns>Json字符串</returns>
        public static string ToJson(DbDataReader dataReader)
        {
            StringBuilder jsonString = new StringBuilder();
            jsonString.Append("[");
            while (dataReader.Read())
            {
                jsonString.Append("{");
                for (int i = 0; i < dataReader.FieldCount; i++)
                {
                    Type type = dataReader.GetFieldType(i);
                    string strKey = dataReader.GetName(i);
                    string strValue = dataReader[i].ToString();
                    jsonString.Append("\"" + strKey + "\":");
                    strValue = StringFormat(strValue, type);
                    if (i < dataReader.FieldCount - 1)
                    {
                        jsonString.Append(strValue + ",");
                    }
                    else
                    {
                        jsonString.Append(strValue);
                    }
                }
                jsonString.Append("},");
            }
            dataReader.Close();
            jsonString.Remove(jsonString.Length - 1, 1);
            jsonString.Append("]");
            return jsonString.ToString();
        }
        #endregion

        #region  DataSet轉換為Json
        /// <summary>
        /// DataSet轉換為Json
        /// </summary>
        /// <param name="dataSet">DataSet對象</param>
        /// <returns>Json字符串</returns>
        public static string ToJson(DataSet dataSet)
        {
            string jsonString = "{";
            foreach (DataTable table in dataSet.Tables)
            {
                jsonString += "\"" + table.TableName + "\":" + ToJson(table) + ",";
            }
            jsonString = jsonString.TrimEnd(',');
            return jsonString + "}";
        }
        #endregion

        #region 過濾特殊字符
        /// <summary>
        /// 過濾特殊字符
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private static string String2Json(String s)
        {
            System.Text.StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
            {
                char c = s.ToCharArray()[i];

                switch (c)
                {
                    case '\"':
                        sb.Append("\\\""); break;
                    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:
                        sb.Append(c); break;
                }
            }
            return sb.ToString();
        }
        #endregion

        #region 格式化字符型、日期型、布爾型
        /// <summary>
        /// 格式化字符型、日期型、布爾型
        /// </summary>
        /// <param name="str"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static string StringFormat(string str, Type type)
        {
            if (type == typeof(string))
            {
                str = String2Json(str);
                str = "\"" + str + "\"";
            }
            else if (type == typeof(DateTime))
            {
                str = "\"" + Convert.ToDateTime(str).ToShortDateString() + "\"";
            }
            else if (type == typeof(bool))
            {
                str = str.ToLower();
            }

            if (str.Length == 0)
                str = "\"\"";

            return str;
        }
        #endregion

        #region XML轉化為Json
        /// <summary>
        ///  XML轉化為Json
        /// </summary>
        /// <param name="Xml">XML 字符串</param>
        /// <returns></returns>
        public static string XML_Json(string Xml)
        {
            // To convert an XML node contained in string xml into a JSON string   
            XmlDocument Xmldoc = new XmlDocument();
            Xmldoc.LoadXml(Xml);
            string jsonText = JsonConvert.SerializeXmlNode(Xmldoc);
            return jsonText;
        }
        #endregion

        /// <summary>
        /// 生成Json格式
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string GetJson<T>(T obj)
        {
            DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
            using (MemoryStream stream = new MemoryStream())
            {
                json.WriteObject(stream, obj);
                string szJson = Encoding.UTF8.GetString(stream.ToArray()); return szJson;
            }
        }
        /// <summary>
        /// 獲取Json的Model
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="szJson"></param>
        /// <returns></returns>
        public static T ParseFromJson<T>(string szJson)
        {
            T obj = Activator.CreateInstance<T>();
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
                return (T)serializer.ReadObject(ms);
            }
        }

       
    }

下班了,不多寫了,寫的很匆忙。兩個JsonHelper,建議大家用上邊的,因為所以科學道理,你不用,我也沒法~!

@陳卧龍的博客

 
         
 
        
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM