首页 / JSON / C#验证json是否合法
C#验证json是否合法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#验证json是否合法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7903字,纯文字阅读大概需要12分钟。
内容图文
![C#验证json是否合法](/upload/InfoBanner/zyjiaocheng/1238/8fbadefacf0247568bff622923f2b01c.jpg)
/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void btnCheckJson_Click(object sender, EventArgs e) { string filepath = null; OpenFileDialog dialog = new OpenFileDialog(); if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { filepath = dialog.FileName; } if (filepath != null) { string json = File.OpenText(filepath).ReadToEnd(); if (JsonSplit.IsJson(json))//传入的json串 { MessageBox.Show("json格式合法"); } else { MessageBox.Show("json格式不合法"); } } } }
internal class JsonSplit { private static bool IsJsonStart(refstring 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 == ‘]‘); } } returnfalse; } internalstaticbool IsJson(string json) { int errIndex; return IsJson(json, out errIndex); } internalstaticbool IsJson(string json, outint 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; returnfalse; } i = i + length - 1; } if (cs.isError) { errIndex = i; returnfalse; } } return !cs.arrayStart && !cs.jsonStart; } returnfalse; } ///<summary>/// 获取值的长度(当Json值嵌套以"{"或"["开头时) ///</summary>privatestaticint GetValueLength(string json, bool breakOnErr, outint 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; } } elseif (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;//长度比索引+1break; } } } return len; } ///<summary>/// 字符状态 ///</summary>privateclass CharState { internalbool jsonStart = false;//以 "{"开始了...internalbool setDicValue = false;// 可以设置字典值了。internalbool escapeChar = false;//以"\"转义符号开始了///<summary>/// 数组开始【仅第一开头才算】,值嵌套的以【childrenStart】来标识。 ///</summary>internalbool arrayStart = false;//以"[" 符号开始了internalbool childrenStart = false;//子级嵌套开始了。///<summary>/// 【0 初始状态,或 遇到“,”逗号】;【1 遇到“:”冒号】 ///</summary>internalint state = 0; ///<summary>/// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】 ///</summary>internalint keyStart = 0; ///<summary>/// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】 ///</summary>internalint valueStart = 0; internalbool isError = false;//是否语法错误。internalvoid 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);//重复出现。 } elseif (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>privatestaticbool 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;//开始。returntrue; } #endregionbreak; 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; returntrue; } // cs.isError = !cs.jsonStart && cs.state == 0;#endregionbreak; case‘[‘: #region 中括号开始 if (!cs.jsonStart) { cs.arrayStart = true; returntrue; } elseif (cs.jsonStart && cs.state == 1) { cs.childrenStart = true; returntrue; } #endregionbreak; case‘]‘: #region 中括号结束 if (cs.arrayStart && !cs.jsonStart && cs.keyStart <= 2 && cs.valueStart <= 0)//[{},333]//这样结束。 { cs.keyStart = 0; cs.valueStart = 0; cs.arrayStart = false; returntrue; } #endregionbreak; case‘"‘: case‘\‘‘: #region 引号 if (cs.jsonStart || cs.arrayStart) { if (cs.state == 0)//key阶段,有可能是数组["aa",{}] { if (cs.keyStart <= 0) { cs.keyStart = (c == ‘"‘ ? 3 : 2); returntrue; } elseif ((cs.keyStart == 2 && c == ‘\‘‘) || (cs.keyStart == 3 && c == ‘"‘)) { if (!cs.escapeChar) { cs.keyStart = -1; returntrue; } else { cs.escapeChar = false; } } } elseif (cs.state == 1 && cs.jsonStart)//值阶段必须是Json开始了。 { if (cs.valueStart <= 0) { cs.valueStart = (c == ‘"‘ ? 3 : 2); returntrue; } elseif ((cs.valueStart == 2 && c == ‘\‘‘) || (cs.valueStart == 3 && c == ‘"‘)) { if (!cs.escapeChar) { cs.valueStart = -1; returntrue; } else { cs.escapeChar = false; } } } } #endregionbreak; case‘:‘: #region 冒号 if (cs.jsonStart && cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 0) { if (cs.keyStart == 1) { cs.keyStart = -1; } cs.state = 1; returntrue; } // cs.isError = !cs.jsonStart || (cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1);#endregionbreak; 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; returntrue; } } elseif (cs.arrayStart && cs.keyStart <= 2) { cs.keyStart = 0; //if (cs.keyStart == 1) //{ // cs.keyStart = -1; //}returntrue; } #endregionbreak; case‘‘: case‘\r‘: case‘\n‘://[ "a",\r\n{} ]case‘\0‘: case‘\t‘: if (cs.keyStart <= 0 && cs.valueStart <= 0) //cs.jsonStart && { returntrue;//跳过空格。 } break; default: //值开头。。if (c == ‘\\‘) //转义符号 { if (cs.escapeChar) { cs.escapeChar = false; } else { cs.escapeChar = true; returntrue; } } else { cs.escapeChar = false; } if (cs.jsonStart || cs.arrayStart) // Json 或数组开始了。 { if (cs.keyStart <= 0 && cs.state == 0) { cs.keyStart = 1;//无引号的 } elseif (cs.valueStart <= 0 && cs.state == 1 && cs.jsonStart)//只有Json开始才有值。 { cs.valueStart = 1;//无引号的 } } break; } returnfalse; } }
原文:https://www.cnblogs.com/yyangjing/p/13047857.html
内容总结
以上是互联网集市为您收集整理的C#验证json是否合法全部内容,希望文章能够帮你解决C#验证json是否合法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。