为了使您的包装类被序列化后,其内部字典能够以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");
string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented);
Console.WriteLine(json);
Console.WriteLine();
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 };
json = JsonConvert.SerializeObject(list, Formatting.Indented);
Console.WriteLine(json);
Console.WriteLine();
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
ToJson()
之前,对数组调用JsonConvert.SerializeObject
方法。最终结果将是相同的。 - Liam[JsonProperty]
属性来消除属性名称。这就是为什么你需要转换器的原因。 - Brian Rogers