轶哥博客

妄图改变世界的全栈程序员。

ASP.NET 5 MVC 6 Web API JSON序化

  ASP.NET 5 MVC 6 Web API (C#)默认支持自动序化XML和JSON格式数据。然而自动序化的JSON数据在很多方面是存在问题的,比如部分符号和JSON字符串数组的问题。

输出符合JavaScript标准的JSON字符串

  目前比较适合正式生产场合的、不容易出现错误的解决方案是自行序化。尽管ASP.NET WEB API已经具备自动序化的能力,但序化出来的内容并不能完全符合JavaScript规范,比如中文不能够很好的进行unicode转换,部分数值未以字符串方式输出(没有引号,或者变成了单引号)。为了避免出现结果差异,我们默认将所有数据都转换为字符串或字符串数组,再由JavaScript自动将数据转换成对应的类型。

     /// <summary>
     /// JSON序列化辅助类
     /// </summary>
    public class JSONHelper
    {
        protected System.Collections.ArrayList arrData = new System.Collections.ArrayList();
        protected string _error_code = string.Empty;
        protected string _error_detail_code = string.Empty;
        protected string _error_message = string.Empty;
        protected string _result = string.Empty;
        protected bool _success = true;
        public void AddItem(string name, string value)
        {
            arrData.Add("\"" + name + "\":" + "\"" + value + "\"");
        }
        public void AddResult(string value)
        {
            _result = value;
        }
        public void ItemOk()
        {
            arrData.Add("<BR>");
        }
        #region 设置success为TURE,代表成功
        public bool success
        {
            get
            {
                return _success;
            }
            set
            {
                //如设置为true则清空error
                if (success) _error_code = string.Empty;
                _success = value;
            }
        }
        public string error_code
        {
            get
            {
                return _error_code;
            }
            set
            {
                _error_code = value;
                _success = false;
            }
        }

        public string error_detail_code
        {
            get
            {
                return _error_detail_code;
            }
            set
            {
                _error_detail_code = value;
            }
        }
        public string error_message
        {
            get
            {
                return _error_message;
            }
            set
            {
                _error_message = value;
            }
        }
        #endregion

        //序列化JSON对象,得到返回的JSON代码
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("{");
            if (_success)
            {
                sb.Append("\"status\":\"OK\",");
                sb.Append("\"result\":");
                if(_result == string.Empty)
                {
                    int index = 0;
                    sb.Append("[{");
                    if (arrData.Count <= 0)
                    {
                        sb.Append("}]");
                    }
                    else
                    {
                        foreach (string val in arrData)
                        {
                            index++;
                            if (val != "<BR>")
                            {
                                sb.Append(val + ",");
                            }
                            else
                            {
                                sb = sb.Replace(",", "", sb.Length - 1, 1);
                                sb.Append("},");
                                if (index < arrData.Count)
                                {
                                    sb.Append("{");
                                }
                            }
                        }
                        sb = sb.Replace(",", "", sb.Length - 1, 1);
                        sb.Append("]");
                    }
                }
                else
                {
                    sb.Append(_result);
                }
            }
            else
            {
                sb.Append("\"status\":\"Error\",");
                sb.Append("\"error_code\":\"" + _error_code.Replace("\"", "\\\"") + "\",");
                sb.Append("\"error_detail_code\":\"" + _error_detail_code.Replace("\"", "\\\"") + "\",");
                sb.Append("\"error_message\":\"" + _error_message.Replace("\"", "\\\"") + "\"");
            }


            sb.Append("}");
            return unicode_js(sb.ToString());
        }

        /// <summary>
        /// 中文转unicode(符合js规则的)
        /// </summary>
        /// <returns></returns>
        public string unicode_js(string str)
        {
            string outStr = "";
            if (!string.IsNullOrEmpty(str))
            {
                for (int i = 0; i < str.Length; i++)
                {
                    if (Regex.IsMatch(str[i].ToString(), @"[\u4e00-\u9fa5]")) { outStr += "\\u" + ((int)str[i]).ToString("x"); }
                    else { outStr += str[i]; }
                }
            }
            return outStr;
        }

        /// <summary>
        /// 将Unicode编码转换为汉字,支持英文数字等字符串和Unicode编码字符串混合
        /// </summary>
        /// <param name="str">含有Unicode编码字符串</param>
        /// <returns>汉字字符串</returns>
        public string UniToGB(string str)
        {
            string StrGb = "";
            int i = 0;
            MatchCollection mc = Regex.Matches(str, @"[url=file://\\u([\w]{2})([\w]{2]\\u([\w]{2})([\w]{2[/url]})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            byte[] bts = new byte[2];
            if (mc.Count != 0)
            {
                foreach (Match m in mc)
                {
                    bts[0] = (byte)int.Parse(m.Groups[2].Value, System.Globalization.NumberStyles.HexNumber);
                    bts[1] = (byte)int.Parse(m.Groups[1].Value, System.Globalization.NumberStyles.HexNumber);
                    string r = Encoding.Unicode.GetString(bts);//Unicode转为汉字
                    i++;
                    if (i == 1)
                    {
                        StrGb = str.Replace(m.Groups[0].Value, r);
                    }
                    else
                    {
                        StrGb = StrGb.Replace(m.Groups[0].Value, r);
                    }
                }
                return StrGb;
            }
            else
            {
                return str;
            }
        }
    }

可能用到的引用:

using System;
using System.Data;
using System.Text;
using Microsoft.Extensions.Configuration;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.Security.Cryptography;

将数据库返回的数据转换成JSON格式

    /// <summary>
    /// DataTable 转换成Json 操作类
    /// </summary>
    public static class ConvertJson
    {
        #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 Datatable转换为Json

        /// <summary>
        /// Datatable转换为Json
        /// </summary>
        /// <param name="table">Datatable对象</param>
        /// <returns>Json字符串</returns>
        public static string ToJson(DataTable dt)
        {
            StringBuilder jsonString = new StringBuilder();
            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>
        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

        /// <summary>
        /// 格式化整数型、字符型、日期型、布尔型
        /// </summary>
        /// <param name="str"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static string StringFormat(string str, Type type)
        {
            if (type == typeof(int) || type == typeof(string))
            {
                str = String2Json(str);
                str = "\"" + str + "\"";
            }
            else if (type == typeof(DateTime))
            {
                str = "\"" + str + "\"";
            }
            else if (type == typeof(bool))
            {
                str = str.ToLower();
            }
            else if (type != typeof(string) && string.IsNullOrEmpty(str))
            {
                str = "\"" + str + "\"";
            }
            return str;
        }

        #region 私有方法
        /// <summary>
        /// 过滤特殊字符
        /// </summary>
        /// <param name="s">字符串</param>
        /// <returns>json字符串</returns>
        private static string String2Json(String s)
        {
            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
    }

以上代码怎么用?

用法非常简单,遵循REST模式。Rest模式有四种操作:

  • POST /uri 创建
  • DELETE /uri/xxx 删除
  • PUT /uri/xxx 更新或创建
  • GET /uri/xxx 查看

错误返回格式

{
"status": "Error",
"error_code": "404",//出错代码
"error_detail_code":"40401",//具体代码
"error_message": "40401: File or folder not found at the specified path"//详细的出错信息
}

成功返回格式

{
"status": "OK",
"result": "相应的结果"
}

具体用法

第一步,实例化:

JSONHelper json = new JSONHelper();//实例化json处理类

其它用法见实例:

                        SqlConnection mySqlConnection = new SqlConnection(); //实例化数据库连接类
                        DB db = new DB();//实例化数据库类
                        JSONHelper json = new JSONHelper();//实例化json处理类
                        mySqlConnection.ConnectionString = db.ConnectionString();//新建连接对象并设置其连接字符串属性

                        string sqlStr = "select * where XXX";//SQL语句

                        string backstring = "error";
                        try
                        {
                            mySqlConnection.Open();//打开连接
                            SqlCommand mycmd = new SqlCommand(sqlStr, mySqlConnection);//新建SqlCommand对象
                            SqlDataReader sdr = mycmd.ExecuteReader();//ExecuteReader方法将 CommandText 发送到 Connection 并生成一个 SqlDataReader
                            DataTable datatable = new DataTable();//定义一个DataTable
                            datatable = db.ConvertDataReaderToDataTable(sdr);//将SqlDataReader转换为DataTable
                            sdr.Close();//关闭SqlDataReader
                            mycmd.Dispose();//释放mycmd的资源
                            backstring = ConvertJson.ToJson(datatable);//转换为json字符串
                            json.success = true;//成功标识
                            json.AddResult(backstring);//添加一个标识

                        }
                        catch (SqlException ex)
                        {   //捕捉错误并处理
                            json.error_code = "502";
                            json.error_detail_code = "10001";
                            json.error_message = ex.Message;
                        }
                        catch (Exception ex)
                        {   //捕捉错误并处理
                            json.error_code = "502";
                            json.error_detail_code = "10003";
                            json.error_message = ex.Message;
                        }
                        finally
                        {
                            mySqlConnection.Close();//关闭连接
                        }
                        backstring = json.ToString();//编码其中的中文数据并返回json字符串
                        return backstring;
                    }

以上错误代码请自行定义。

ConvertJson.ToJson(datatable);是DataTable 转换成Json 操作。

当然,也可以这样用:

                           json.success = true;//成功标识

                            while (sdr.Read())
                            {
                                DateTime dt1 = DateTime.Parse(sdr["start_time"].ToString());
                                DateTime dt2 = DateTime.Parse(sdr["over_time"].ToString());
                                DateTime nowtome = DateTime.Now.Date;
                                if (DateTime.Compare(dt1, nowtome) <= 0 && DateTime.Compare(nowtome, dt2) <= 0)
                                {
                                    json.AddItem("image_title_" + sdr["Id"].ToString(), sdr["image_title"].ToString());
                                    json.AddItem("image_url_" + sdr["Id"].ToString(), sdr["image_url"].ToString());//添加一个标识
                                }
                            }

                            json.ItemOk();//json字符串处理完毕

只需要依葫芦画瓢,即可输出准确的JSON字符串数据。

  上一篇 (Node.js HTTP Web 静态资源服务器代码)
下一篇 (ASP.NET 5 MVC 6 Web API 上传图片)