为了序列化您的包装器类,使其内部字典出现在 JSON 中,就好像包装器不存在一样,您需要一个自定义 JsonConverter。 JsonConverter 让您可以直接控制对特定类进行序列化和/或反序列化的内容。
以下是适用于您的情况的转换器。由于您并没有真正提供有关您的包装类的任何详细信息,只是它有一个名为 values 的字段来保存字典,因此我使用反射来访问它。如果您的类具有直接操作字典的公共方法,您可以更改转换器以使用这些方法,如果您愿意的话。代码如下:
class DictionaryWrapperConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(MyWrapper));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
MyWrapper wrapper = (MyWrapper)value;
FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance);
JObject jo = JObject.FromObject(field.GetValue(wrapper));
jo.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
MyWrapper wrapper = new MyWrapper();
FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(wrapper, jo.ToObject(field.FieldType));
return wrapper;
}
}
要将自定义转换器绑定到您的包装类,您可以在类定义中添加[JsonConverter] 属性:
[JsonConverter(typeof(DictionaryWrapperConverter))]
class MyWrapper : IEnumerable
{
Dictionary<string, string> values = new Dictionary<string, string>();
public void Add(string key, string value)
{
values.Add(key, value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return values.GetEnumerator();
}
}
这是一个完整的演示,展示了转换器的运行情况,首先序列化和反序列化包装器类的单个实例,然后序列化和反序列化包装器列表:
class Program
{
static void Main(string[] args)
{
MyWrapper wrapper = new MyWrapper();
wrapper.Add("foo", "bar");
wrapper.Add("fizz", "bang");
// serialize single wrapper instance
string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented);
Console.WriteLine(json);
Console.WriteLine();
// deserialize single wrapper instance
wrapper = JsonConvert.DeserializeObject<MyWrapper>(json);
foreach (KeyValuePair<string, string> kvp in wrapper)
{
Console.WriteLine(kvp.Key + "=" + kvp.Value);
}
Console.WriteLine();
Console.WriteLine("----------\n");
MyWrapper wrapper2 = new MyWrapper();
wrapper2.Add("a", "1");
wrapper2.Add("b", "2");
wrapper2.Add("c", "3");
List<MyWrapper> list = new List<MyWrapper> { wrapper, wrapper2 };
// serialize list of wrappers
json = JsonConvert.SerializeObject(list, Formatting.Indented);
Console.WriteLine(json);
Console.WriteLine();
// deserialize list of wrappers
list = JsonConvert.DeserializeObject<List<MyWrapper>>(json);
foreach (MyWrapper w in list)
{
foreach (KeyValuePair<string, string> kvp in w)
{
Console.WriteLine(kvp.Key + "=" + kvp.Value);
}
Console.WriteLine();
}
}
}
输出:
{
"foo": "bar",
"fizz": "bang"
}
foo=bar
fizz=bang
----------
[
{
"foo": "bar",
"fizz": "bang"
},
{
"a": "1",
"b": "2",
"c": "3"
}
]
foo=bar
fizz=bang
a=1
b=2
c=3