json操作类
json操作类
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace Comm
6 {
7 public class Json
8 {
9 /// <summary>
10 /// 用于构建属性值的回调
11 /// </summary>
12 /// <param name="Property"></param>
13 public delegate void SetProperties(JsonObject Property);
14
15 /// <summary>
16 /// JsonObject属性值类型
17 /// </summary>
18 public enum JsonPropertyType
19 {
20 String,
21 Object,
22 Array,
23 Number,
24 Bool,
25 Null
26 }
27
28 /// <summary>
29 /// JSON通用对象
30 /// </summary>
31 public class JsonObject
32 {
33 private Dictionary<String, JsonProperty> _property;
34
35 public JsonObject()
36 {
37 this._property = null;
38 }
39
40 public JsonObject(String jsonString)
41 {
42 this.Parse(ref jsonString);
43 }
44
45 public JsonObject(SetProperties callback)
46 {
47 if (callback != null)
48 {
49 callback(this);
50 }
51 }
52
53 /// <summary>
54 /// Json字符串解析
55 /// </summary>
56 /// <param name="jsonString"></param>
57 private void Parse(ref String jsonString)
58 {
59 int len = jsonString.Length;
60 if (String.IsNullOrEmpty(jsonString) || jsonString.Substring(0, 1) != "{" || jsonString.Substring(jsonString.Length - 1, 1) != "}")
61 {
62 throw new ArgumentException("传入文本不符合Json格式!" + jsonString);
63 }
64 Stack<Char> stack = new Stack<char>();
65 Stack<Char> stackType = new Stack<char>();
66 StringBuilder sb = new StringBuilder();
67 Char cur;
68 bool convert = false;
69 bool isValue = false;
70 JsonProperty last = null;
71 for (int i = 1; i <= len - 2; i++)
72 {
73 cur = jsonString[i];
74 if (cur == '}')
75 {
76 ;
77 }
78 if (cur == ' ' && stack.Count == 0)
79 {
80 ;
81 }
82 else if ((cur == '\'' || cur == '\"') && !convert && stack.Count == 0 && !isValue)
83 {
84 sb.Length = 0;
85 stack.Push(cur);
86 }
87 else if ((cur == '\'' || cur == '\"') && !convert && stack.Count > 0 && stack.Peek() == cur && !isValue)
88 {
89 stack.Pop();
90 }
91 else if ((cur == '[' || cur == '{') && stack.Count == 0)
92 {
93 stackType.Push(cur == '[' ? ']' : '}');
94 sb.Append(cur);
95 }
96 else if ((cur == ']' || cur == '}') && stack.Count == 0 && stackType.Peek() == cur)
97 {
98 stackType.Pop();
99 sb.Append(cur);
100 }
101 else if (cur == ':' && stack.Count == 0 && stackType.Count == 0 && !isValue)
102 {
103 last = new JsonProperty();
104 this[sb.ToString()] = last;
105 isValue = true;
106 sb.Length = 0;
107 }
108 else if (cur == ',' && stack.Count == 0 && stackType.Count == 0)
109 {
110 if (last != null)
111 {
112
113 String temp = sb.ToString();
114 last.Parse(ref temp);
115 }
116 isValue = false;
117 sb.Length = 0;
118 }
119 else
120 {
121 sb.Append(cur);
122 }
123 }
124 if (sb.Length > 0 && last != null && last.Type == JsonPropertyType.Null)
125 {
126 String temp = sb.ToString();
127 last.Parse(ref temp);
128 }
129 }
130
131 /// <summary>
132 /// 获取属性
133 /// </summary>
134 /// <param name="PropertyName"></param>
135 /// <returns></returns>
136 public JsonProperty this[String PropertyName]
137 {
138 get
139 {
140 JsonProperty result = null;
141 if (this._property != null && this._property.ContainsKey(PropertyName))
142 {
143 result = this._property[PropertyName];
144 }
145 return result;
146 }
147 set
148 {
149 if (this._property == null)
150 {
151 this._property = new Dictionary<string, JsonProperty>(StringComparer.OrdinalIgnoreCase);
152 }
153 if (this._property.ContainsKey(PropertyName))
154 {
155 this._property[PropertyName] = value;
156 }
157 else
158 {
159 this._property.Add(PropertyName, value);
160 }
161 }
162 }
163
164 /// <summary>
165 /// 通过此泛型函数可直接获取指定类型属性的值
166 /// </summary>
167 /// <typeparam name="T"></typeparam>
168 /// <param name="PropertyName"></param>
169 /// <returns></returns>
170 public virtual T Properties<T>(String PropertyName) where T : class
171 {
172 JsonProperty p = this[PropertyName];
173 if (p != null)
174 {
175 return p.GetValue<T>();
176 }
177 return default(T);
178 }
179
180 /// <summary>
181 /// 获取属性名称列表
182 /// </summary>
183 /// <returns></returns>
184 public String[] GetPropertyNames()
185 {
186 if (this._property == null)
187 return null;
188 String[] keys = null;
189 if (this._property.Count > 0)
190 {
191 keys = new String[this._property.Count];
192 this._property.Keys.CopyTo(keys, 0);
193 }
194 return keys;
195 }
196
197 /// <summary>
198 /// 移除一个属性
199 /// </summary>
200 /// <param name="PropertyName"></param>
201 /// <returns></returns>
202 public JsonProperty RemoveProperty(String PropertyName)
203 {
204 if (this._property != null && this._property.ContainsKey(PropertyName))
205 {
206 JsonProperty p = this._property[PropertyName];
207 this._property.Remove(PropertyName);
208 return p;
209 }
210 return null;
211 }
212
213 /// <summary>
214 /// 是否为空对象
215 /// </summary>
216 /// <returns></returns>
217 public bool IsNull()
218 {
219 return this._property == null;
220 }
221
222 public override string ToString()
223 {
224 return this.ToString("");
225 }
226
227 /// <summary>
228 /// ToString...
229 /// </summary>
230 /// <param name="format">格式化字符串</param>
231 /// <returns></returns>
232 public virtual string ToString(String format)
233 {
234 if (this.IsNull())
235 {
236 return "{}";
237 }
238 else
239 {
240 StringBuilder sb = new StringBuilder();
241 foreach (String key in this._property.Keys)
242 {
243 sb.Append(",");
244 sb.Append(key).Append(": ");
245 sb.Append(this._property[key].ToString(format));
246
247 }
248 if (this._property.Count > 0)
249 {
250 sb.Remove(0, 1);
251 }
252 sb.Insert(0, "{");
253 sb.Append("}");
254 return sb.ToString();
255 }
256 }
257 }
258
259 /// <summary>
260 /// JSON对象属性
261 /// </summary>
262 public class JsonProperty
263 {
264 private JsonPropertyType _type;
265 private String _value;
266 private JsonObject _object;
267 private List<JsonProperty> _list;
268 private bool _bool;
269 private double _number;
270
271 public JsonProperty()
272 {
273 this._type = JsonPropertyType.Null;
274 this._value = null;
275 this._object = null;
276 this._list = null;
277 }
278
279 public JsonProperty(Object value)
280 {
281 this.SetValue(value);
282 }
283
284
285 public JsonProperty(String jsonString)
286 {
287 this.Parse(ref jsonString);
288 }
289
290
291 /// <summary>
292 /// Json字符串解析
293 /// </summary>
294 /// <param name="jsonString"></param>
295 public void Parse(ref String jsonString)
296 {
297 if (String.IsNullOrEmpty(jsonString))
298 {
299 this.SetValue(null);
300 }
301 else
302 {
303 string first = jsonString.Substring(0, 1);
304 string last = jsonString.Substring(jsonString.Length - 1, 1);
305 if (first == "[" && last == "]")
306 {
307 this.SetValue(this.ParseArray(ref jsonString));
308 }
309 else if (first == "{" && last == "}")
310 {
311 this.SetValue(this.ParseObject(ref jsonString));
312 }
313 else if ((first == "'" || first == "\"") && first == last)
314 {
315 this.SetValue(this.ParseString(ref jsonString));
316 }
317 else if (jsonString == "true" || jsonString == "false")
318 {
319 this.SetValue(jsonString == "true" ? true : false);
320 }
321 else if (jsonString == "null")
322 {
323 this.SetValue(null);
324 }
325 else
326 {
327 double d = 0;
328 if (double.TryParse(jsonString, out d))
329 {
330 this.SetValue(d);
331 }
332 else
333 {
334 this.SetValue(jsonString);
335 }
336 }
337 }
338 }
339
340 /// <summary>
341 /// Json Array解析
342 /// </summary>
343 /// <param name="jsonString"></param>
344 /// <returns></returns>
345 private List<JsonProperty> ParseArray(ref String jsonString)
346 {
347 List<JsonProperty> list = new List<JsonProperty>();
348 int len = jsonString.Length;
349 StringBuilder sb = new StringBuilder();
350 Stack<Char> stack = new Stack<char>();
351 Stack<Char> stackType = new Stack<Char>();
352 bool conver = false;
353 Char cur;
354 for (int i = 1; i <= len - 2; i++)
355 {
356 cur = jsonString[i];
357 if (Char.IsWhiteSpace(cur) && stack.Count == 0)
358 {
359 ;
360 }
361 else if ((cur == '\'' && stack.Count == 0 && !conver && stackType.Count == 0) || (cur == '\"' && stack.Count == 0 && !conver && stackType.Count == 0))
362 {
363 sb.Length = 0;
364 sb.Append(cur);
365 stack.Push(cur);
366 }
367 else if (cur == '\\' && stack.Count > 0 && !conver)
368 {
369 sb.Append(cur);
370 conver = true;
371 }
372 else if (conver == true)
373 {
374 conver = false;
375
376 if (cur == 'u')
377 {
378 sb.Append(new char[] { cur, jsonString[i + 1], jsonString[i + 2], jsonString[i + 3] });
379 i += 4;
380 }
381 else
382 {
383 sb.Append(cur);
384 }
385 }
386 else if ((cur == '\'' || cur == '\"') && !conver && stack.Count > 0 && stack.Peek() == cur && stackType.Count == 0)
387 {
388 sb.Append(cur);
389 list.Add(new JsonProperty(sb.ToString()));
390 stack.Pop();
391 }
392 else if ((cur == '[' || cur == '{') && stack.Count == 0)
393 {
394 if (stackType.Count == 0)
395 {
396 sb.Length = 0;
397 }
398 sb.Append(cur);
399 stackType.Push((cur == '[' ? ']' : '}'));
400 }
401 else if ((cur == ']' || cur == '}') && stack.Count == 0 && stackType.Count > 0 && stackType.Peek() == cur)
402 {
403 sb.Append(cur);
404 stackType.Pop();
405 if (stackType.Count == 0)
406 {
407 list.Add(new JsonProperty(sb.ToString()));
408 sb.Length = 0;
409 }
410
411 }
412 else if (cur == ',' && stack.Count == 0 && stackType.Count == 0)
413 {
414 if (sb.Length > 0)
415 {
416 list.Add(new JsonProperty(sb.ToString()));
417 sb.Length = 0;
418 }
419 }
420 else
421 {
422 sb.Append(cur);
423 }
424 }
425 if (stack.Count > 0 || stackType.Count > 0)
426 {
427 list.Clear();
428 throw new ArgumentException("无法解析Json Array对象!");
429 }
430 else if (sb.Length > 0)
431 {
432 list.Add(new JsonProperty(sb.ToString()));
433 }
434 return list;
435 }
436
437
438 /// <summary>
439 /// Json String解析
440 /// </summary>
441 /// <param name="jsonString"></param>
442 /// <returns></returns>
443 private String ParseString(ref String jsonString)
444 {
445 int len = jsonString.Length;
446 StringBuilder sb = new StringBuilder();
447 bool conver = false;
448 Char cur;
449 for (int i = 1; i <= len - 2; i++)
450 {
451 cur = jsonString[i];
452 if (cur == '\\' && !conver)
453 {
454 conver = true;
455 }
456 else if (conver == true)
457 {
458 conver = false;
459 if (cur == '\\' || cur == '\"' || cur == '\'' || cur == '/')
460 {
461 sb.Append(cur);
462 }
463 else
464 {
465 if (cur == 'u')
466 {
467 String temp = new String(new char[] { cur, jsonString[i + 1], jsonString[i + 2], jsonString[i + 3] });
468 sb.Append((char)Convert.ToInt32(temp, 16));
469 i += 4;
470 }
471 else
472 {
473 switch (cur)
474 {
475 case 'b':
476 sb.Append('\b');
477 break;
478 case 'f':
479 sb.Append('\f');
480 break;
481 case 'n':
482 sb.Append('\n');
483 break;
484 case 'r':
485 sb.Append('\r');
486 break;
487 case 't':
488 sb.Append('\t');
489 break;
490 }
491 }
492 }
493 }
494 else
495 {
496 sb.Append(cur);
497 }
498 }
499 return sb.ToString();
500 }
501
502 /// <summary>
503 /// Json Object解析
504 /// </summary>
505 /// <param name="jsonString"></param>
506 /// <returns></returns>
507 private JsonObject ParseObject(ref String jsonString)
508 {
509 return new JsonObject(jsonString);
510 }
511
512 /// <summary>
513 /// 定义一个索引器,如果属性是非数组的,返回本身
514 /// </summary>
515 /// <param name="index"></param>
516 /// <returns></returns>
517 public JsonProperty this[int index]
518 {
519 get
520 {
521 JsonProperty r = null;
522 if (this._type == JsonPropertyType.Array)
523 {
524 if (this._list != null && (this._list.Count - 1) >= index)
525 {
526 r = this._list[index];
527 }
528 }
529 else if (index == 0)
530 {
531 return this;
532 }
533 return r;
534 }
535 }
536
537 /// <summary>
538 /// 提供一个字符串索引,简化对Object属性的访问
539 /// </summary>
540 /// <param name="PropertyName"></param>
541 /// <returns></returns>
542 public JsonProperty this[String PropertyName]
543 {
544 get
545 {
546 if (this._type == JsonPropertyType.Object)
547 {
548 return this._object[PropertyName];
549 }
550 else
551 {
552 return null;
553 }
554 }
555 set
556 {
557 if (this._type == JsonPropertyType.Object)
558 {
559 this._object[PropertyName] = value;
560 }
561 else
562 {
563 throw new NotSupportedException("Json属性不是对象类型!");
564 }
565 }
566 }
567
568 /// <summary>
569 /// JsonObject值
570 /// </summary>
571 public JsonObject Object
572 {
573 get
574 {
575 if (this._type == JsonPropertyType.Object)
576 return this._object;
577 return null;
578 }
579 }
580
581 /// <summary>
582 /// 字符串值
583 /// </summary>
584 public String Value
585 {
586 get
587 {
588 if (this._type == JsonPropertyType.String)
589 {
590 return this._value;
591 }
592 else if (this._type == JsonPropertyType.Number)
593 {
594 return this._number.ToString();
595 }
596 return null;
597 }
598 }
599
600 public JsonProperty Add(Object value)
601 {
602 if (this._type != JsonPropertyType.Null && this._type != JsonPropertyType.Array)
603 {
604 throw new NotSupportedException("Json属性不是Array类型,无法添加元素!");
605 }
606 if (this._list == null)
607 {
608 this._list = new List<JsonProperty>();
609 }
610 JsonProperty jp = new JsonProperty(value);
611 this._list.Add(jp);
612 this._type = JsonPropertyType.Array;
613 return jp;
614 }
615
616 /// <summary>
617 /// Array值,如果属性是非数组的,则封装成只有一个元素的数组
618 /// </summary>
619 public List<JsonProperty> Items
620 {
621 get
622 {
623 if (this._type == JsonPropertyType.Array)
624 {
625 return this._list;
626 }
627 else
628 {
629 List<JsonProperty> list = new List<JsonProperty>();
630 list.Add(this);
631 return list;
632 }
633 }
634 }
635
636 /// <summary>
637 /// 数值
638 /// </summary>
639 public double Number
640 {
641 get
642 {
643 if (this._type == JsonPropertyType.Number)
644 {
645 return this._number;
646 }
647 else
648 {
649 return double.NaN;
650 }
651 }
652 }
653
654 public void Clear()
655 {
656 this._type = JsonPropertyType.Null;
657 this._value = String.Empty;
658 this._object = null;
659 if (this._list != null)
660 {
661 this._list.Clear();
662 this._list = null;
663 }
664 }
665
666 public Object GetValue()
667 {
668 if (this._type == JsonPropertyType.String)
669 {
670 return this._value;
671 }
672 else if (this._type == JsonPropertyType.Object)
673 {
674 return this._object;
675 }
676 else if (this._type == JsonPropertyType.Array)
677 {
678 return this._list;
679 }
680 else if (this._type == JsonPropertyType.Bool)
681 {
682 return this._bool;
683 }
684 else if (this._type == JsonPropertyType.Number)
685 {
686 return this._number;
687 }
688 else
689 {
690 return null;
691 }
692 }
693
694 public virtual T GetValue<T>() where T : class
695 {
696 return (GetValue() as T);
697 }
698
699 public virtual void SetValue(Object value)
700 {
701 if (value is String)
702 {
703 this._type = JsonPropertyType.String;
704 this._value = (String)value;
705 }
706 else if (value is List<JsonProperty>)
707 {
708 this._list = ((List<JsonProperty>)value);
709 this._type = JsonPropertyType.Array;
710 }
711 else if (value is JsonObject)
712 {
713 this._object = (JsonObject)value;
714 this._type = JsonPropertyType.Object;
715 }
716 else if (value is bool)
717 {
718 this._bool = (bool)value;
719 this._type = JsonPropertyType.Bool;
720 }
721 else if (value == null)
722 {
723 this._type = JsonPropertyType.Null;
724 }
725 else
726 {
727 double d = 0;
728 if (double.TryParse(value.ToString(), out d))
729 {
730 this._number = d;
731 this._type = JsonPropertyType.Number;
732 }
733 else
734 {
735 throw new ArgumentException("错误的参数类型!");
736 }
737 }
738 }
739
740 public virtual int Count
741 {
742 get
743 {
744 int c = 0;
745 if (this._type == JsonPropertyType.Array)
746 {
747 if (this._list != null)
748 {
749 c = this._list.Count;
750 }
751 }
752 else
753 {
754 c = 1;
755 }
756 return c;
757 }
758 }
759
760 public JsonPropertyType Type
761 {
762 get { return this._type; }
763 }
764
765 public override string ToString()
766 {
767 return this.ToString("");
768 }
769
770
771 public virtual string ToString(String format)
772 {
773 StringBuilder sb = new StringBuilder();
774 if (this._type == JsonPropertyType.String)
775 {
776 sb.Append("'").Append(this._value).Append("'");
777 return sb.ToString();
778 }
779 else if (this._type == JsonPropertyType.Bool)
780 {
781 return this._bool ? "true" : "false";
782 }
783 else if (this._type == JsonPropertyType.Number)
784 {
785 return this._number.ToString();
786 }
787 else if (this._type == JsonPropertyType.Null)
788 {
789 return "null";
790 }
791 else if (this._type == JsonPropertyType.Object)
792 {
793 return this._object.ToString();
794 }
795 else
796 {
797 if (this._list == null || this._list.Count == 0)
798 {
799 sb.Append("[]");
800 }
801 else
802 {
803 sb.Append("[");
804 if (this._list.Count > 0)
805 {
806 foreach (JsonProperty p in this._list)
807 {
808 sb.Append(p.ToString());
809 sb.Append(", ");
810 }
811 sb.Length -= 2;
812 }
813 sb.Append("]");
814 }
815 return sb.ToString();
816 }
817 }
818 }
819 }
820 }
821