用C#实现一个迷你json库,无需引入dll(可直接放到Unity中使用)

C#微型JSON库解析与序列化实战
本文介绍了如何在C# WinForm应用中使用一个轻量级的JSON库,无需引入额外DLL。通过示例展示了JSON对象与数组之间的转换,包括字符串序列化与反序列化操作,以及嵌套结构的处理。代码简洁实用,适用于简单场景下的JSON处理。

一、前言

最近在搞C#winform窗体应用实现一个微型下载器功能。过程中需要解析json数据,又不想引入一个dll,从GitHub上找到了一个json库源码,并做了微调,实测可用。

二、使用

1、json obj转string
JSONObject jsonObj = new JSONObject();
jsonObj["key_1"] = "value_1";
jsonObj["key_2"] = 666;
string jsonStr = JSONConvert.SerializeObject(jsonObj);
Console.WriteLine(jsonStr);

输出结果

{"key_1":"value_1","key_2":666}
2、json array转string
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < 3; ++i)
{
    JSONObject jsonObjItem = new JSONObject();
    jsonObjItem["key_1"] = "value_1";
    jsonArray.Add(jsonObjItem);
}
string jsonStr = JSONConvert.SerializeArray(jsonArray);
Console.WriteLine(jsonStr);

输出结果

[{"key_1":"value_1"},{"key_1":"value_1"},{"key_1":"value_1"}]
3、json obj嵌套json array,转string
JSONObject jsonObj = new JSONObject();
jsonObj["test_key"] = "test_value";
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < 3; ++i)
{
    JSONObject jsonObjItem = new JSONObject();
    jsonObjItem["key_1"] = "value_1";
    jsonArray.Add(jsonObjItem);
}
jsonObj["test_array"] = jsonArray;
string jsonStr = JSONConvert.SerializeObject(jsonObj);
Console.WriteLine(jsonStr);

输出结果

{"test_key":"test_value","test_array":[{"key_1":"value_1"},{"key_1":"value_1"},{"key_1":"value_1"}]}
4、json string转json obj
string jsonStr = "{\"key_1\":\"value_1\",\"key_2\":666}";
JSONObject jsonObj =  JSONConvert.DeserializeObject(jsonStr);
Console.WriteLine((string)jsonObj["key_1"]);
Console.WriteLine(int.Parse((string)jsonObj["key_2"]));

输出结果

value_1
666
5、json string(带数组)转json obj
string jsonStr = "{\"test_key\":\"test_value\",\"test_array\":[{\"key_1\":\"value_1\"},{\"key_1\":\"value_1\"},{\"key_1\":\"value_1\"}]}";
JSONObject jsonObj = JSONConvert.DeserializeObject(jsonStr);
Console.WriteLine((string)jsonObj["test_key"]);
JSONArray jsonArray = (JSONArray)jsonObj["test_array"];
JSONObject item = jsonArray[0] as JSONObject;
Console.WriteLine((string)item["key_1"]);

输出结果

test_value
value_1

三、迷你json库代码

using System.Collections.Generic;
using System.Text;


public static class JSONConvert
{
    #region Global Variables
    private static char[] _charary;
    private static int _aryend;

    #endregion

    #region JSON Deserialization

    /// <summary>
    /// Convert string to JSONObject
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    private static JSONObject DeserializeSingletonObject(ref int left)
    {
        JSONObject localjson = new JSONObject();
        while (left <= _aryend)
        {
            char c = _charary[left];
            if (c == ' ' || c == '\r' || c == '\n' || c == '\t')  //skip empty char
            {
                left++;
                continue;
            }
            if (c == ',')
            {
                left++;
                continue;
            }
            char r = '\0';
            if (c == '\"' || c == '\'')     //beginning of key
            {
                left++;
                r = c;
            }
            else if (c == '}')      //end of JSONObject
            {
                left++;
                break;
            }
            int column = left;
            if (r == '\0')
            {
                while (_charary[column] != ':') column++;
            }
            else
            {
                while (!(_charary[column] == r && _charary[column - 1] != '\\' && _charary[column + 1] == ':')) column++;
            }
            string key = new string(_charary, left, column - left);         //get the key
            if (r == '\0')
                left = column + 1;
            else
                left = column + 2;
            c = _charary[left];
            while (c == ' ' || c == '\r' || c == '\n' || c == '\t')  //skip empty char
            {
                left++;
                c = _charary[left];
            }
            if (c == '\"' || c == '\'')     //if value is string
            {
                left++;
                int strend = left;
                while (_charary[strend] != c || _charary[strend - 1] == '\\') strend++;
                localjson[key] = new string(_charary, left, strend - left);
                left = strend + 1;
            }
            else if (c == '{') // JSONObject
            {
                left++;
                localjson[key] = DeserializeSingletonObject(ref left);
            }
            else if (c == '[')     //JSONArray
            {
                left++;
                localjson[key] = DeserializeSingletonArray(ref left);
            }
            else
            {
                //other class, such as boolean, int
                //all are converted to string, it can be enriched if in need
                int comma = left;
                char co = _charary[comma];
                while (co != ',' && co != '}')
                {
                    comma++;
                    co = _charary[comma];
                }
                int em = comma - 1;
                co = _charary[em];
                while (co == ' ' || co == '\r' || co == '\n' || co == '\t')
                {
                    em--;
                    co = _charary[em];
                }
                localjson[key] = new string(_charary, left, em - left + 1);
                left = comma;
            }
        }
        return localjson;
    }

    /// <summary>
    /// Convert string to JSONArray
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    private static JSONArray DeserializeSingletonArray(ref int left)
    {
        JSONArray jsary = new JSONArray();
        while (left <= _aryend)
        {
            char c = _charary[left];
            if (c == ' ' || c == '\r' || c == '\n' || c == '\t')  //skip empty char
            {
                left++;
                continue;
            }
            if (c == ',')
            {
                left++;
                continue;
            }
            if (c == ']')
            {
                left++;
                break;
            }
            if (c == '{') //JSONObject
            {
                left++;
                jsary.Add(DeserializeSingletonObject(ref left));
            }
            else if (c == '[')     //JSONArray
            {
                left++;
                jsary.Add(DeserializeSingletonArray(ref left));
            }
            else if (c == '\"' || c == '\'')            //string
            {
                left++;
                int strend = left;
                while (_charary[strend] != c || _charary[strend - 1] == '\\') strend++;
                jsary.Add(new string(_charary, left, strend - left));
                left = strend + 1;
            }
            else
            {
                //other class, such as boolean, int
                //all are converted to string, it can be enriched if in need
                int comma = left;
                char co = _charary[comma];
                while (co != ',' && co != ']')
                {
                    comma++;
                    co = _charary[comma];
                }
                int em = comma - 1;
                co = _charary[em];
                while (co == ' ' || co == '\r' || co == '\n' || co == '\t')
                {
                    em--;
                    co = _charary[em];
                }
                jsary.Add(new string(_charary, left, em - left + 1));
                left = comma;
            }
        }
        return jsary;
    }

    #endregion

    #region Public Interface

    /// <summary>
    /// Get a JSONObject instance from char[]
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static JSONObject DeserializeCharToObject(char[] input)
    {
        _charary = input;
        _aryend = _charary.Length - 1;
        while (_aryend > 0)
            if (_charary[_aryend] != '}')
                _aryend--;
            else
                break;
        int start = 0;
        while (start < _aryend)
            if (_charary[start] != '{')
                start++;
            else
                break;
        start++;
        if (_aryend < start + 1)
            return null;
        return DeserializeSingletonObject(ref start);
    }

    /// <summary>
    /// Get a JSONObject instance from string
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static JSONObject DeserializeObject(string input)
    {
        return DeserializeCharToObject(input.ToCharArray());     //The first char must be '{'
    }

    /// <summary>
    /// Get a JSONArray instance from char[]
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static JSONArray DeserializeCharsToArray(char[] input)
    {
        _charary = input;
        _aryend = _charary.Length - 1;
        while (_aryend > 0)
            if (_charary[_aryend] != ']')
                _aryend--;
            else
                break;
        int start = 0;
        while (start < _aryend)
            if (_charary[start] != '[')
                start++;
            else
                break;
        start++;
        if (_aryend < start + 1)
            return null;
        return DeserializeSingletonArray(ref start);
    }

    /// <summary>
    /// Get a JSONArray instance from string
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static JSONArray DeserializeArray(string input)
    {
        return DeserializeCharsToArray(input.ToCharArray());
    }
    /// <summary>
    /// Serialize a JSONObject instance
    /// </summary>
    /// <param name="jsonObject"></param>
    /// <returns></returns>
    public static string SerializeObject(JSONObject jsonObject)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("{");
        foreach (KeyValuePair<string, object> kvp in jsonObject)
        {
            if (kvp.Value is JSONObject)
            {
                sb.Append(string.Format("\"{0}\":{1},", kvp.Key, SerializeObject((JSONObject)kvp.Value)));
            }
            else if (kvp.Value is JSONArray)
            {
                sb.Append(string.Format("\"{0}\":{1},", kvp.Key, SerializeArray((JSONArray)kvp.Value)));
            }
            else if (kvp.Value is string)
            {
                sb.Append(string.Format("\"{0}\":\"{1}\",", kvp.Key, kvp.Value));
            }
            else if (kvp.Value is int || kvp.Value is long)
            {
                sb.Append(string.Format("\"{0}\":{1},", kvp.Key, kvp.Value));
            }
            else
            {
                sb.Append(string.Format("\"{0}\":\"{1}\",", kvp.Key, ""));
            }
        }
        if (sb.Length > 1)
            sb.Remove(sb.Length - 1, 1);
        sb.Append("}");
        return sb.ToString();
    }

    /// <summary>
    /// Serialize a JSONArray instance
    /// </summary>
    /// <param name="jsonArray"></param>
    /// <returns></returns>
    public static string SerializeArray(JSONArray jsonArray)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("[");
        for (int i = 0; i < jsonArray.Count; i++)
        {
            if (jsonArray[i] is JSONObject)
            {
                sb.Append(string.Format("{0},", SerializeObject((JSONObject)jsonArray[i])));
            }
            else if (jsonArray[i] is JSONArray)
            {
                sb.Append(string.Format("{0},", SerializeArray((JSONArray)jsonArray[i])));
            }
            else if (jsonArray[i] is string)
            {
                sb.Append(string.Format("\"{0}\",", jsonArray[i]));
            }
            else
            {
                sb.Append(string.Format("\"{0}\",", ""));
            }

        }
        if (sb.Length > 1)
            sb.Remove(sb.Length - 1, 1);
        sb.Append("]");
        return sb.ToString();
    }

    #endregion
}


public class JSONObject : Dictionary<string, object>
{
    public void put(string key, string value)
    {
        this[key] = value;
    }

    public void put(string key, int value)
    {
        this[key] = value.ToString();

    }
}


public class JSONArray : List<object>
{ }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林新发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值