强制将空JSON数组转换为Dictionary类型 [英] Force conversion of empty JSON array to Dictionary type
问题描述
问题是,PHP中的json_encode()
函数使正在读取其输出的工具含糊不清.在PHP中,列表和字典都是array
的相同类型.
The problem is, that json_encode()
function in PHP leaves ambiguity for tools which are reading its output. In PHP both lists and dictionaries are same type of array
.
echo json_encode([]); // []
echo json_encode(["5" => "something"]); // {"5": "something"}
在JSON.NET中,我想同时将[]
和{"5": "something"}
都强制转换为Dictionary<string, string>
类型.但是,它将[]
识别为Dictionary的禁止结构,并引发异常.
In JSON.NET I want to force both []
and {"5": "something"}
to convert to Dictionary<string, string>
type. However it recognizes []
as prohibited structure for Dictionary and throws an Exception.
我可以快速将空的JSON数组保留为空或强制将其转换为空的字典类型吗?
Can I quickly leave empty JSON arrays nulled or force them to convert to empty Dictionary type?
最终解决方案
我修改了接受的答案,以使其通用且可用于其他类型.
I modified accepted answer to make it generic and reusable for other types.
public class DictionaryOrEmptyArrayConverter<T,F> : JsonConverter
{
public override bool CanWrite { get { return false; } }
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dictionary<T, F>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.StartArray:
reader.Read();
if (reader.TokenType == JsonToken.EndArray)
return new Dictionary<T, F>();
else
throw new JsonSerializationException("Non-empty JSON array does not make a valid Dictionary!");
case JsonToken.Null:
return null;
case JsonToken.StartObject:
var tw = new System.IO.StringWriter();
var writer = new JsonTextWriter(tw);
writer.WriteStartObject();
int initialDepth = reader.Depth;
while (reader.Read() && reader.Depth > initialDepth)
{
writer.WriteToken(reader);
}
writer.WriteEndObject();
writer.Flush();
return JsonConvert.DeserializeObject<Dictionary<T, F>>(tw.ToString());
default:
throw new JsonSerializationException("Unexpected token!");
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
您应将其与JSON对象一起使用,如下例所示:
You should use it with your JSON object as in example below:
public class Company
{
public string industry_name { get; set; }
[JsonConverter(typeof(DictionaryOrEmptyArrayConverter<int, Upgrade>))]
public Dictionary<int, Upgrade> upgrades { get; set; }
}
public class Upgrade
{
public int level { get; set; }
}
它允许您使用DeserializeObject
方法将JSON字符串快速转换为对象:
It allows you to quickly convert JSON string to objects with DeserializeObject
method:
var result = JsonConvert.DeserializeObject<Company>(jsonString);
推荐答案
您可以使用自定义的JsonConverter
来做到这一点,尽管我认为此解决方案仍有待改进:
You can do it with a custom JsonConverter
, although I think this solution leaves a bit to be desired:
private class DictionaryConverter : JsonConverter
{
public override bool CanWrite { get { return false; } }
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dictionary<string, string>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
reader.Read();
if (reader.TokenType == JsonToken.EndArray)
return new Dictionary<string, string>();
else
throw new JsonSerializationException("Non-empty JSON array does not make a valid Dictionary!");
}
else if (reader.TokenType == JsonToken.Null)
{
return null;
}
else if (reader.TokenType == JsonToken.StartObject)
{
Dictionary<string, string> ret = new Dictionary<string, string>();
reader.Read();
while (reader.TokenType != JsonToken.EndObject)
{
if (reader.TokenType != JsonToken.PropertyName)
throw new JsonSerializationException("Unexpected token!");
string key = (string)reader.Value;
reader.Read();
if (reader.TokenType != JsonToken.String)
throw new JsonSerializationException("Unexpected token!");
string value = (string)reader.Value;
ret.Add(key, value);
reader.Read();
}
return ret;
}
else
{
throw new JsonSerializationException("Unexpected token!");
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
在 https://dotnetfiddle.net/zzlzH4
这篇关于强制将空JSON数组转换为Dictionary类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!