一、LitJson编码问题

我在将对象转成Json的时候,中文并没有正确显示,LitJson的编码用的Unicode,存储中文是\uXXXX类型的。可以把字符串转换成非正则表达式式的字符串来解决。
方法一: (此方法我没试过)
付原文链接,可以自己试一下。
https://blog.csdn.net/qq_41211080/article/details/89343988

1
string saveJson = Regex.Unescape(JsonMapper.ToJson(save));

方法二:(亲测有效,包括转义字符都可以正确转换)

1
2
3
4
5
6
public static string JsonUTF8toUnicode(string jsonStr)  
{
Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
var str = reg.Replace(jsonStr, delegate (Match m) { return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString(); });
return str;
}

二、JsonMapper.ToJson()方法会将属性方法也转为Json字符串

我在将某个类转为json的时候,遇到了报错:RuntimeError: divide by zero搜索了一番,发现是一个属性里面用到了除法,并且分母为0导致的,后来经过查阅资料发现,LitJson在转属性的时候,会将属性也转为json字符。解决办法就是忽略掉属性方法。
给需要忽略的属性添加[LitJson.Extensions.JsonIgnore]标签

1
2
[LitJson.Extensions.JsonIgnore]  
public long YourAttributeFunction{get;set;}

三、Litjson的JsonMapper.ToObject<>()方法不支持枚举类型

我有一个数据结构是这样的

1
2
3
4
5
6
public enum Example {  
Example1,
Example2
}

public Dictionary<Example, int> exampleObj = new Dictionary<Example, int>();

这里,如果使用JsonMapper.ToJson()方法是可以正确的序列化对象的,但是返过来将序列化好的json转为对象就会报错了。处理办法及更详细的解释这里附上大佬的链接

https://www.cnblogs.com/littleperilla/p/16548598.html

不过原作者使用的版本和我的有很大区别,这里我发一下我的修改方法。

打开JsonMapper.cs 找到private static object ReadValue(Type inst_type, JsonReader reader)
对照我的修改来改一下吧,原作者说的也不是很清楚,property参数在原版中是string类型,这里去掉强制转换。改为Object类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
        private static object ReadValue(Type inst_type, JsonReader reader)  
{ reader.Read();

if (reader.Token == JsonToken.ArrayEnd)
return null;

Type underlying_type = Nullable.GetUnderlyingType(inst_type);
Type value_type = underlying_type ?? inst_type;

if (reader.Token == JsonToken.Null)
{#if NETSTANDARD1_5
if (inst_type.IsClass() || underlying_type != null) {
return null; }#else
if (inst_type.IsClass || underlying_type != null)
{ return null;
}#endif

throw new JsonException(String.Format(
"Can't assign null to an instance of type {0}",
inst_type)); }
if (reader.Token == JsonToken.Double ||
reader.Token == JsonToken.Int ||
reader.Token == JsonToken.Long ||
reader.Token == JsonToken.String ||
reader.Token == JsonToken.Boolean)
{
Type json_type = reader.Value.GetType();

if (value_type.IsAssignableFrom(json_type))
return reader.Value;

// If there's a custom importer that fits, use it
if (custom_importers_table.ContainsKey(json_type) &&
custom_importers_table[json_type].ContainsKey(
value_type)) {
ImporterFunc importer =
custom_importers_table[json_type][value_type];

return importer(reader.Value);
}
// Maybe there's a base importer that works
if (base_importers_table.ContainsKey(json_type) &&
base_importers_table[json_type].ContainsKey(
value_type)) {
ImporterFunc importer =
base_importers_table[json_type][value_type];

return importer(reader.Value);
}
// Maybe it's an enum
#if NETSTANDARD1_5
if (value_type.IsEnum())
return Enum.ToObject (value_type, reader.Value);#else
if (value_type.IsEnum)
return Enum.ToObject(value_type, reader.Value);
#endif
// Try using an implicit conversion operator
MethodInfo conv_op = GetConvOp(value_type, json_type);

if (conv_op != null)
return conv_op.Invoke(null,
new object[] { reader.Value });

// No luck
throw new JsonException(String.Format(
"Can't assign value '{0}' (type {1}) to type {2}",
reader.Value, json_type, inst_type));
}
object instance = null;

if (reader.Token == JsonToken.ArrayStart)
{
AddArrayMetadata(inst_type);
ArrayMetadata t_data = array_metadata[inst_type];

if (!t_data.IsArray && !t_data.IsList)
throw new JsonException(String.Format(
"Type {0} can't act as an array",
inst_type));
IList list;
Type elem_type;

if (!t_data.IsArray)
{ list = (IList)Activator.CreateInstance(inst_type);
elem_type = t_data.ElementType;
} else
{
list = new ArrayList();
elem_type = inst_type.GetElementType();
}
list.Clear();

while (true)
{ object item = ReadValue(elem_type, reader);
if (item == null && reader.Token == JsonToken.ArrayEnd)
break;

list.Add(item);
}
if (t_data.IsArray)
{ int n = list.Count;
instance = Array.CreateInstance(elem_type, n);

for (int i = 0; i < n; i++)
((Array)instance).SetValue(list[i], i);
} else
instance = list;

} else if (reader.Token == JsonToken.ObjectStart)
{ AddObjectMetadata(value_type);
ObjectMetadata t_data = object_metadata[value_type];

instance = Activator.CreateInstance(value_type);

while (true)
{ reader.Read();

if (reader.Token == JsonToken.ObjectEnd)
break;

Object property = reader.Value;

if (t_data.Properties.ContainsKey((string)property))
{ PropertyMetadata prop_data =
t_data.Properties[(string)property];

if (prop_data.IsField)
{ ((FieldInfo)prop_data.Info).SetValue(
instance, ReadValue(prop_data.Type, reader));
} else
{
PropertyInfo p_info =
(PropertyInfo)prop_data.Info;

if (p_info.CanWrite)
p_info.SetValue(
instance, ReadValue(prop_data.Type, reader),
null);
else
ReadValue(prop_data.Type, reader);
}
} else
{
if (!t_data.IsDictionary)
{
if (!reader.SkipNonMembers)
{ throw new JsonException(String.Format(
"The type {0} doesn't have the " +
"property '{1}'",
inst_type, property)); } else
{
ReadSkip(reader);
continue;
} } else
{
var dicTypes = instance.GetType().GetGenericArguments();
var converter = System.ComponentModel.TypeDescriptor.GetConverter(dicTypes[0]);
if (converter != null)
{ property = converter.ConvertFromString((string)property);
t_data.ElementType = dicTypes[1];
} }
((IDictionary)instance).Add(
property, ReadValue(
t_data.ElementType, reader));
}
}
}
return instance;
}