C# JsonHelper 操作辅助类,拿来直接用
程序员文章站
2022-06-05 13:36:05
四个主要操作类:jsonconverter 、jsonhelper 、jsonsplit 、ajaxresult
一、jsonconverter:
自定义查询对象转换动...
四个主要操作类:jsonconverter 、jsonhelper 、jsonsplit 、ajaxresult
一、jsonconverter:
自定义查询对象转换动态类、object动态类转换json包、json转换object动态类、datareader转换为json、dataset转换为json、datatable转成json、datatable转换为json 、格式化字符型日期型布尔型、过滤特殊字符等
using system; using system.collections.generic; using system.text; using system.data; using system.linq; using system.web.script.serialization; using system.collections; namespace common { public class jsonconverter { /// <summary> /// 自定义查询对象转换动态类 /// add yuangang by 2015-05-19 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static dynamic jsonclass(object obj) { return convertjson(serialize(obj, true)); } /// <summary> /// object动态类转换json包 /// add yuangang by 2015-05-19 /// </summary> /// <param name="obj">对象</param> /// <param name="dateconvert">时间戳是否转换成日期类型</param> /// <returns></returns> public static string serialize(object obj, bool dateconvert = false) { javascriptserializer jss = new javascriptserializer(); var str = jss.serialize(obj); if (dateconvert) { str = system.text.regularexpressions.regex.replace(str, @"\\/date\((\d+)\)\\/", match => { datetime dt = new datetime(1970, 1, 1); dt = dt.addmilliseconds(long.parse(match.groups[1].value)); dt = dt.tolocaltime(); return dt.tostring("yyyy-mm-dd hh:mm:ss"); }); } return str; } /// <summary> /// json转换object动态类 /// add yuangang by 2015-05-19 /// </summary> /// <param name="json"></param> /// <returns></returns> public static dynamic convertjson(string json) { javascriptserializer jss = new javascriptserializer(); jss.registerconverters(new javascriptconverter[] { new dynamicjsonconverter() }); dynamic dy = jss.deserialize(json, typeof(object)) as dynamic; return dy; } /// <summary> /// datareader转换为json /// </summary> /// <param name="datareader">datareader对象</param> /// <returns>json字符串</returns> public static string tojson(idatareader datareader) { try { 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("},"); } if (!datareader.isclosed) { datareader.close(); } jsonstring.remove(jsonstring.length - 1, 1); jsonstring.append("]"); if (jsonstring.length == 1) { return "[]"; } return jsonstring.tostring(); } catch (exception ex) { throw ex; } } /// <summary> /// dataset转换为json /// add yuangang by 2015-05-19 /// </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 + "}"; } /// <summary> /// datatable转成json /// add yuangang by 2015-05-19 /// </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] is dbnull ? string.empty : 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(); } /// <summary> /// datatable转换为json /// add yuangang by 2015-05-19 /// </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("]"); if (jsonstring.length == 1) { return "[]"; } return jsonstring.tostring(); } /// <summary> /// 格式化字符型、日期型、布尔型 /// add yuangang by 2015-05-19 /// </summary> /// <param name="str"></param> /// <param name="type"></param> /// <returns></returns> private static string stringformat(string str, type type) { if (type != typeof(string) && string.isnullorempty(str)) { str = "\"" + str + "\""; } else if (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(byte[])) { str = "\"" + str + "\""; } else if (type == typeof(guid)) { str = "\"" + str + "\""; } return str; } /// <summary> /// 过滤特殊字符 /// add yuangang by 2015-05-19 /// </summary> /// <param name="s"></param> /// <returns></returns> public 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; case '\v': sb.append("\\v"); break; case '\0': sb.append("\\0"); break; default: sb.append(c); break; } } return sb.tostring(); } public static string getdatagridjsonbydataset(dataset ds, string totalproperty, string root) { return getdatagridjsonbydatatable(ds.tables[0], totalproperty, root); } public static string getdatagridjsonbydatatable(datatable dt, string totalproperty, string root) { stringbuilder jsonbuilder = new stringbuilder(); jsonbuilder.append("({\"" + totalproperty + "\":\"" + dt.rows.count + "\","); jsonbuilder.append("\""); jsonbuilder.append(root); jsonbuilder.append("\":["); for (int i = 0; i < dt.rows.count; i++) { jsonbuilder.append("{"); for (int j = 0; j < dt.columns.count; j++) { jsonbuilder.append("\""); jsonbuilder.append(dt.columns[j].columnname); jsonbuilder.append("\":\""); jsonbuilder.append(dt.rows[i][j].tostring()); jsonbuilder.append("\","); } jsonbuilder.remove(jsonbuilder.length - 1, 1); jsonbuilder.append("},"); } jsonbuilder.remove(jsonbuilder.length - 1, 1); jsonbuilder.append("]"); jsonbuilder.append("})"); return jsonbuilder.tostring(); } public static string gettreejsonbydataset(dataset ds) { return gettreejsonbydatatable(ds.tables[0]); } public static string gettreejsonbydatatable(datatable datatable) { datatable dt = formatdatatablefortree(datatable); stringbuilder jsonbuilder = new stringbuilder(); jsonbuilder.append("["); for (int i = 0; i < dt.rows.count; i++) { jsonbuilder.append("{"); for (int j = 0; j < dt.columns.count; j++) { jsonbuilder.append("\'"); if (dt.columns[j].columnname == "leaf") { string leafvalue = dt.rows[i][j].tostring(); if (!string.isnullorempty(leafvalue)) { jsonbuilder.append(dt.columns[j].columnname); jsonbuilder.append("\':\'"); jsonbuilder.append(dt.rows[i][j].tostring()); jsonbuilder.append("\',"); } else { jsonbuilder.remove(jsonbuilder.length - 1, 1); } } else if (dt.columns[j].columnname == "customurl") { jsonbuilder.remove(jsonbuilder.length - 1, 1); jsonbuilder.append(dt.columns[j].columnname); jsonbuilder.append(":\'"); jsonbuilder.append(dt.rows[i][j].tostring()); jsonbuilder.append("\',"); } else { jsonbuilder.append(dt.columns[j].columnname); jsonbuilder.append("\':\'"); jsonbuilder.append(dt.rows[i][j].tostring()); jsonbuilder.append("\',"); } } jsonbuilder.remove(jsonbuilder.length - 1, 1); jsonbuilder.append("},"); } jsonbuilder.remove(jsonbuilder.length - 1, 1); jsonbuilder.append("]"); return jsonbuilder.tostring(); } private static datatable formatdatatablefortree(datatable dt) { datatable dttree = new datatable(); dttree.columns.add("id", typeof(string)); dttree.columns.add("text", typeof(string)); dttree.columns.add("leaf", typeof(string)); dttree.columns.add("cls", typeof(string)); dttree.columns.add("customurl", typeof(string)); dttree.acceptchanges(); for (int i = 0; i < dt.rows.count; i++) { datarow drtree = dttree.newrow(); drtree["id"] = dt.rows[i]["id"].tostring(); drtree["text"] = dt.rows[i]["text"].tostring(); if (dt.rows[i]["leaf"].tostring() == "y") { drtree["leaf"] = "true"; drtree["cls"] = "file"; } else { drtree["cls"] = "folder"; } drtree["customurl"] = dt.rows[i]["customurl"].tostring(); dttree.rows.add(drtree); } return dttree; } } /// <summary> /// 动态json解析 /// add yuangang by 2015-05-19 /// </summary> public class dynamicjsonobject : system.dynamic.dynamicobject { private idictionary<string, object> dictionary { get; set; } public dynamicjsonobject(idictionary<string, object> dictionary) { this.dictionary = dictionary; } public override bool trygetmember(system.dynamic.getmemberbinder binder, out object result) { result = this.dictionary[binder.name]; if (result is idictionary<string, object>) { result = new dynamicjsonobject(result as idictionary<string, object>); } else if (result is arraylist && (result as arraylist) is idictionary<string, object>) { result = new list<dynamicjsonobject>((result as arraylist).toarray().select(x => new dynamicjsonobject(x as idictionary<string, object>))); } else if (result is arraylist) { result = new list<object>((result as arraylist).toarray()); } return this.dictionary.containskey(binder.name); } } /// <summary> /// 动态json转换 /// add yuangang by 2015-05-19 /// </summary> public class dynamicjsonconverter : javascriptconverter { public override object deserialize(idictionary<string, object> dictionary, type type, javascriptserializer serializer) { if (dictionary == null) throw new argumentnullexception("dictionary"); if (type == typeof(object)) { return new dynamicjsonobject(dictionary); } return null; } public override idictionary<string, object> serialize(object obj, javascriptserializer serializer) { throw new notimplementedexception(); } public override ienumerable<type> supportedtypes { get { return new system.collections.objectmodel.readonlycollection<type>(new list<type>(new type[] { typeof(object) })); } } } }
二、jsonhelper:json的辅助类
using system.collections.generic; using system.text; using newtonsoft.json; using system.runtime.serialization.json; using system.io; namespace common { /// <summary> /// 提供了一个关于json的辅助类 /// </summary> public class jsonhelper { #region method /// <summary> /// 类对像转换成json格式 /// </summary> /// <returns></returns> public static string tojson(object t) { return jsonconvert.serializeobject(t, newtonsoft.json.formatting.indented, new jsonserializersettings { nullvaluehandling = nullvaluehandling.include }); } /// <summary> /// 类对像转换成json格式 /// </summary> /// <param name="t"></param> /// <param name="hasnullignore">是否忽略null值</param> /// <returns></returns> public static string tojson(object t, bool hasnullignore) { if (hasnullignore) return jsonconvert.serializeobject(t, newtonsoft.json.formatting.indented, new jsonserializersettings { nullvaluehandling = nullvaluehandling.ignore }); else return tojson(t); } /// <summary> /// json格式转换 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="strjson"></param> /// <returns></returns> public static t fromjson<t>(string strjson) where t : class { if (!strjson.isnullorempty()) return jsonconvert.deserializeobject<t>(strjson); return null; } /// <summary> /// 功能描述:将list转换为json /// </summary> /// <param name="a"></param> /// <returns></returns> public static string listtojson(ilist<object> a) { datacontractjsonserializer json = new datacontractjsonserializer(a.gettype()); string szjson = ""; //序列化 using (memorystream stream = new memorystream()) { json.writeobject(stream, a); szjson = encoding.utf8.getstring(stream.toarray()); } return szjson; } #endregion #region property /// <summary> /// 数据状态 /// </summary> public string status { get; set; } /// <summary> /// 提示信息 /// </summary> public string msg { get; set; } /// <summary> /// 回传url /// </summary> public string reurl { get; set; } /// <summary> /// 数据包 /// </summary> public object data { get; set; } #endregion } }
三、jsonsplit:判断字符串是否为json
using system; using system.collections.generic; using system.linq; using system.web; namespace common { /// <summary> /// 判断字符串是否为json /// </summary> public class jsonsplit { private static bool isjsonstart(ref string json) { if (!string.isnullorempty(json)) { json = json.trim('\r', '\n', ' '); if (json.length > 1) { char s = json[0]; char e = json[json.length - 1]; return (s == '{' && e == '}') || (s == '[' && e == ']'); } } return false; } public static bool isjson(string json) { int errindex; return isjson(json, out errindex); } public static bool isjson(string json, out int errindex) { errindex = 0; if (isjsonstart(ref json)) { charstate cs = new charstate(); char c; for (int i = 0; i < json.length; i++) { c = json[i]; if (setcharstate(c, ref cs) && cs.childrenstart)//设置关键符号状态。 { string item = json.substring(i); int err; int length = getvaluelength(item, true, out err); cs.childrenstart = false; if (err > 0) { errindex = i + err; return false; } i = i + length - 1; } if (cs.iserror) { errindex = i; return false; } } return !cs.arraystart && !cs.jsonstart; } return false; } /// <summary> /// 获取值的长度(当json值嵌套以"{"或"["开头时) /// </summary> private static int getvaluelength(string json, bool breakonerr, out int errindex) { errindex = 0; int len = 0; if (!string.isnullorempty(json)) { charstate cs = new charstate(); char c; for (int i = 0; i < json.length; i++) { c = json[i]; if (!setcharstate(c, ref cs))//设置关键符号状态。 { if (!cs.jsonstart && !cs.arraystart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenstart)//正常字符,值状态下。 { int length = getvaluelength(json.substring(i), breakonerr, out errindex);//递归子值,返回一个长度。。。 cs.childrenstart = false; cs.valuestart = 0; //cs.state = 0; i = i + length - 1; } if (breakonerr && cs.iserror) { errindex = i; return i; } if (!cs.jsonstart && !cs.arraystart)//记录当前结束位置。 { len = i + 1;//长度比索引+1 break; } } } return len; } /// <summary> /// 字符状态 /// </summary> private class charstate { internal bool jsonstart = false;//以 "{"开始了... internal bool setdicvalue = false;// 可以设置字典值了。 internal bool escapechar = false;//以"\"转义符号开始了 /// <summary> /// 数组开始【仅第一开头才算】,值嵌套的以【childrenstart】来标识。 /// </summary> internal bool arraystart = false;//以"[" 符号开始了 internal bool childrenstart = false;//子级嵌套开始了。 /// <summary> /// 【0 初始状态,或 遇到“,”逗号】;【1 遇到“:”冒号】 /// </summary> internal int state = 0; /// <summary> /// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】 /// </summary> internal int keystart = 0; /// <summary> /// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】 /// </summary> internal int valuestart = 0; internal bool iserror = false;//是否语法错误。 internal void checkiserror(char c)//只当成一级处理(因为getlength会递归到每一个子项处理) { if (keystart > 1 || valuestart > 1) { return; } //示例 ["aa",{"bbbb":123,"fff","ddd"}] switch (c) { case '{'://[{ "[{a}]":[{"[{b}]":3,"m":"c"}]}] iserror = jsonstart && state == 0;//重复开始错误 同时不是值处理。 break; case '}': iserror = !jsonstart || (keystart != 0 && state == 0);//重复结束错误 或者 提前结束{"aa"}。正常的有{} break; case '[': iserror = arraystart && state == 0;//重复开始错误 break; case ']': iserror = !arraystart || jsonstart;//重复开始错误 或者 json 未结束 break; case '"': case '\'': iserror = !(jsonstart || arraystart); //json 或数组开始。 if (!iserror) { //重复开始 [""",{"" "}] iserror = (state == 0 && keystart == -1) || (state == 1 && valuestart == -1); } if (!iserror && arraystart && !jsonstart && c == '\'')//['aa',{}] { iserror = true; } break; case ':': iserror = !jsonstart || state == 1;//重复出现。 break; case ',': iserror = !(jsonstart || arraystart); //json 或数组开始。 if (!iserror) { if (jsonstart) { iserror = state == 0 || (state == 1 && valuestart > 1);//重复出现。 } else if (arraystart)//["aa,] [,] [{},{}] { iserror = keystart == 0 && !setdicvalue; } } break; case ' ': case '\r': case '\n'://[ "a",\r\n{} ] case '\0': case '\t': break; default: //值开头。。 iserror = (!jsonstart && !arraystart) || (state == 0 && keystart == -1) || (valuestart == -1 && state == 1);// break; } //if (iserror) //{ //} } } /// <summary> /// 设置字符状态(返回true则为关键词,返回false则当为普通字符处理) /// </summary> private static bool setcharstate(char c, ref charstate cs) { cs.checkiserror(c); switch (c) { case '{'://[{ "[{a}]":[{"[{b}]":3,"m":"c"}]}] #region 大括号 if (cs.keystart <= 0 && cs.valuestart <= 0) { cs.keystart = 0; cs.valuestart = 0; if (cs.jsonstart && cs.state == 1) { cs.childrenstart = true; } else { cs.state = 0; } cs.jsonstart = true;//开始。 return true; } #endregion break; case '}': #region 大括号结束 if (cs.keystart <= 0 && cs.valuestart < 2 && cs.jsonstart) { cs.jsonstart = false;//正常结束。 cs.state = 0; cs.keystart = 0; cs.valuestart = 0; cs.setdicvalue = true; return true; } // cs.iserror = !cs.jsonstart && cs.state == 0; #endregion break; case '[': #region 中括号开始 if (!cs.jsonstart) { cs.arraystart = true; return true; } else if (cs.jsonstart && cs.state == 1) { cs.childrenstart = true; return true; } #endregion break; case ']': #region 中括号结束 if (cs.arraystart && !cs.jsonstart && cs.keystart <= 2 && cs.valuestart <= 0)//[{},333]//这样结束。 { cs.keystart = 0; cs.valuestart = 0; cs.arraystart = false; return true; } #endregion break; case '"': case '\'': #region 引号 if (cs.jsonstart || cs.arraystart) { if (cs.state == 0)//key阶段,有可能是数组["aa",{}] { if (cs.keystart <= 0) { cs.keystart = (c == '"' ? 3 : 2); return true; } else if ((cs.keystart == 2 && c == '\'') || (cs.keystart == 3 && c == '"')) { if (!cs.escapechar) { cs.keystart = -1; return true; } else { cs.escapechar = false; } } } else if (cs.state == 1 && cs.jsonstart)//值阶段必须是json开始了。 { if (cs.valuestart <= 0) { cs.valuestart = (c == '"' ? 3 : 2); return true; } else if ((cs.valuestart == 2 && c == '\'') || (cs.valuestart == 3 && c == '"')) { if (!cs.escapechar) { cs.valuestart = -1; return true; } else { cs.escapechar = false; } } } } #endregion break; case ':': #region 冒号 if (cs.jsonstart && cs.keystart < 2 && cs.valuestart < 2 && cs.state == 0) { if (cs.keystart == 1) { cs.keystart = -1; } cs.state = 1; return true; } // cs.iserror = !cs.jsonstart || (cs.keystart < 2 && cs.valuestart < 2 && cs.state == 1); #endregion break; case ',': #region 逗号 //["aa",{aa:12,}] if (cs.jsonstart) { if (cs.keystart < 2 && cs.valuestart < 2 && cs.state == 1) { cs.state = 0; cs.keystart = 0; cs.valuestart = 0; //if (cs.valuestart == 1) //{ // cs.valuestart = 0; //} cs.setdicvalue = true; return true; } } else if (cs.arraystart && cs.keystart <= 2) { cs.keystart = 0; //if (cs.keystart == 1) //{ // cs.keystart = -1; //} return true; } #endregion break; case ' ': case '\r': case '\n'://[ "a",\r\n{} ] case '\0': case '\t': if (cs.keystart <= 0 && cs.valuestart <= 0) //cs.jsonstart && { return true;//跳过空格。 } break; default: //值开头。。 if (c == '\\') //转义符号 { if (cs.escapechar) { cs.escapechar = false; } else { cs.escapechar = true; return true; } } else { cs.escapechar = false; } if (cs.jsonstart || cs.arraystart) // json 或数组开始了。 { if (cs.keystart <= 0 && cs.state == 0) { cs.keystart = 1;//无引号的 } else if (cs.valuestart <= 0 && cs.state == 1 && cs.jsonstart)//只有json开始才有值。 { cs.valuestart = 1;//无引号的 } } break; } return false; } } }
四、ajaxresult:前台ajax请求的统一返回结果类
using system.web.script.serialization; namespace common { /// <summary> /// 前台ajax请求的统一返回结果类 /// </summary> public class ajaxresult { private ajaxresult() { } private bool iserror = false; /// <summary> /// 是否产生错误 /// </summary> public bool iserror { get { return iserror; } } /// <summary> /// 错误信息,或者成功信息 /// </summary> public string message { get; set; } /// <summary> /// 成功可能时返回的数据 /// </summary> public object data { get; set; } #region error public static ajaxresult error() { return new ajaxresult() { iserror = true }; } public static ajaxresult error(string message) { return new ajaxresult() { iserror = true, message = message }; } #endregion #region success public static ajaxresult success() { return new ajaxresult() { iserror = false }; } public static ajaxresult success(string message) { return new ajaxresult() { iserror = false, message = message }; } public static ajaxresult success(object data) { return new ajaxresult() { iserror = false, data = data }; } public static ajaxresult success(object data, string message) { return new ajaxresult() { iserror = false, data = data, message = message }; } #endregion /// <summary> /// 序列化 /// </summary> /// <returns></returns> public override string tostring() { return new javascriptserializer().serialize(this); } } }
常用的一些json操作类,留着备用,需要的朋友的直接拿去用吧。
上一篇: C# winform实现登陆次数限制
下一篇: 谈C# using的用法与好处