一、LitJson编码问题
我在将对象转成Json的时候,中文并没有正确显示,LitJson的编码用的Unicode,存储中文是\uXXXX类型的。可以把字符串转换成非正则表达式式的字符串来解决。
方法一: (此方法我没试过)
付原文链接,可以自己试一下。
https://blog.youkuaiyun.com/qq_41211080/article/details/89343988
string saveJson = Regex.Unescape(JsonMapper.ToJson(save));
方法二:(亲测有效,包括转义字符都可以正确转换)
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]
标签
[LitJson.Extensions.JsonIgnore]
public long YourAttributeFunction{get;set;}
三、Litjson的JsonMapper.ToObject<>()方法不支持枚举类型
我有一个数据结构是这样的
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类型。
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;
}
原文链接:https://qiuchao.net/2023/02/18/LitJsonProblemSummary/