C# 将KeyValuePair自定义序列化为单个属性,而不是单独的;“关键”;及;“价值”;
这就是我的问题。我有一门课看起来像这样C# 将KeyValuePair自定义序列化为单个属性,而不是单独的;“关键”;及;“价值”;,c#,json,serialization,C#,Json,Serialization,这就是我的问题。我有一门课看起来像这样 public class Record { public string Name { get; set; } public KeyValuePair<string, object> Details { get; set; } } { "Name" : "Root", "Details" : { "TestSerialization" : [ {
public class Record
{
public string Name { get; set; }
public KeyValuePair<string, object> Details { get; set; }
}
{
"Name" : "Root",
"Details" :
{
"TestSerialization" :
[
{ "IsChild" : true },
{ "Child1" : "Another KV pair" }
]
}
}
{
//...
{ "key" : "IsChild", "value" : true }
//...
}
但似乎大多数序列化程序都会将键值对序列化为以下内容
public class Record
{
public string Name { get; set; }
public KeyValuePair<string, object> Details { get; set; }
}
{
"Name" : "Root",
"Details" :
{
"TestSerialization" :
[
{ "IsChild" : true },
{ "Child1" : "Another KV pair" }
]
}
}
{
//...
{ "key" : "IsChild", "value" : true }
//...
}
是否有编写器或序列化程序可以完成此任务?如果您愿意编写自定义转换器类,则内置的.NET可以为您提供所需的输出。每个框架版本的转换器的接口都有很大的不同,但总体思路是相同的。我将在这个答案中演示这两个方面
使用Json.Net
在Json.Net中,您需要实现这样一个类。CanConvert
方法告诉Json.Net转换器可以处理什么类型的对象,而WriteJson
方法使用传递给该方法的JsonWriter
和JsonSerializer
将每个实例转换为Json
class KvpConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(KeyValuePair<string, object>);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var kvp = (KeyValuePair<string, object>)value;
writer.WriteStartObject();
writer.WritePropertyName(kvp.Key);
serializer.Serialize(writer, kvp.Value);
writer.WriteEndObject();
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
使用JavaScriptSerializer
.Net版本的转换器称为。与Json.Net类似,SupportedTypes
属性告诉JavaScriptSerializer
转换器处理的对象类型,而Serialize
方法负责重新格式化输出。主要区别在于,在序列化中,您不能直接控制JSON输出;相反,您构建并返回一个IDictionary
,然后序列化程序将其序列化,以代替您正在转换的原始对象。所以不像Json.Net那么灵活,但它仍然足以满足我们在这种情况下的需要。以下是JavaScriptConverter的代码:
class KvpJavaScriptConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get { return new List<Type> { typeof(KeyValuePair<string, object>) }; }
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
KeyValuePair<string, object> kvp = (KeyValuePair<string, object>)obj;
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add(kvp.Key, kvp.Value);
return dict;
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
}
类KvpJavaScriptConverter:JavaScriptConverter
{
公共覆盖IEnumerable SupportedTypes
{
获取{返回新列表{typeof(KeyValuePair)};}
}
公共重写IDictionary序列化(对象obj、JavaScriptSerializer序列化程序)
{
KeyValuePair kvp=(KeyValuePair)obj;
Dictionary dict=新字典();
dict.Add(kvp.Key,kvp.Value);
返回命令;
}
公共重写对象反序列化(IDictionary dictionary、类型、JavaScriptSerializer序列化程序)
{
抛出新的NotImplementedException();
}
}
以下是更新的演示代码:
class Program
{
static void Main(string[] args)
{
var root = new Record
{
Name = "Root",
Details = new KeyValuePair<string, object>("TestSerialization",
new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("IsChild", true),
new KeyValuePair<string, object>("Child1", "Another KV pair")
})
};
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(
new List<JavaScriptConverter> { new KvpJavaScriptConverter() });
string json = serializer.Serialize(root);
Console.WriteLine(json);
}
}
类程序
{
静态void Main(字符串[]参数)
{
var root=新记录
{
Name=“Root”,
详细信息=新的KeyValuePair(“TestSerialization”,
新名单
{
新的KeyValuePair(“IsChild”,true),
新的KeyValuePair(“Child1”,“另一对KV”)
})
};
var serializer=新的JavaScriptSerializer();
serializer.RegisterConverters(
新列表{new KvpJavaScriptConverter()});
string json=serializer.Serialize(根);
Console.WriteLine(json);
}
}
输出与Json.Net演示相同,只是JavaScriptSerializer不支持缩进输出 您可以直接使用JavaScriptSerializer
进行序列化,查看我给出的示例。JavaScriptSerializer
和JsonConvert
,得到了相同的结果,我认为最好使用非第三方DDL,关键是当核心功能存在于JSS
时,那么为什么要使用第三方DLL,你说什么?@ArindamNayak“关键是当JSS有核心功能时,为什么要使用第三方DLL,”。。。那么,莱蒂不在那里吗?这就是他的问题,不是吗?JSS和JsonConvert并没有做你们想让他们做的事情。@AlexAnderson,是的,我同意,重点是JSS和JSON.Net转换成一种相同的格式,具有KeyValue
,这不是必需的,所以我仍然在寻找@Zacht的有用选项。这可以通过自定义转换器使用JavaScriptSerializer或JSON.Net来完成。我已经添加了一个详细的答案,说明如何进行。