可能有一种更快/更简洁的方法来做到这一点,但我是通过将 aJavaScriptConverter
与辅助类型结合来实现的。
转换器(比看起来简单,灵感来自这里):
private class RecordPropertyJavaScriptConverter : JavaScriptConverter
{
private static readonly Type[] _supportedTypes = new[]
{
typeof(record_group)
};
public override IEnumerable<Type> SupportedTypes
{
get { return _supportedTypes; }
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (type == typeof(record_group))
{
record_group obj = new record_group();
var kvp = dictionary.Single();
obj.Key = kvp.Key;
obj.Values = serializer.ConvertToType<IEnumerable<object>>(kvp.Value);
return obj;
}
return null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var dataObj = obj as record_group;
if (dataObj != null)
{
return new Dictionary<string, object>
{
{dataObj.Key, dataObj.Values}
};
}
return new Dictionary<string, object>();
}
}
助手类型:
private class record_group
{
public string Key;
public IEnumerable<object> Values;
}
序列化代码:
var groups = recList.GroupBy(r => r.Key)
.Select(g => new record_group { Key = g.Key, Values = g.Select(r => r.Value) });
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new [] {new RecordPropertyJavaScriptConverter()});
string json = serializer.Serialize(groups);
输出(带有一些标签,我添加了换行符):
[{"P_Flavor":["Berry","Cedar","Cherry","Coffee"]},
{"P_Winery":["Lyeth"]},
{"P_Body":["Elegant","Firm","Firm Tannins","Polished","Supple","Tannins"]},
{"P_Name":["A Red Blend"]},
{"P_DateReviewed":["08/31/95"]},
{"P_WineID":[34699]},
{"P_Score":[5]}]
然后可以进行反序列化(使用与上面相同的序列化程序实例),如下所示:
var deserialized = serializer.Deserialize<IEnumerable<record_group>>(json);
var properties = deserialized.SelectMany(g => g.Values.Select(v => new record_property { Key = g.Key, Value = v }));