将包含对象 属性 的 poco 序列化为 Json
Serialize poco containing object property into Json
我有一个 class 需要序列化以传递给另一个系统。
class 包含一个定义为对象的 属性,因为对象将包含的 class 类型在运行时可能会有所不同。
我的 classes 看起来像这个简化的模型;
public class MyTestXML
{
public string String1 { get; set; }
public string String2 { get; set; }
[System.Xml.Serialization.XmlElementAttribute("First", typeof(MyFirstObject),
Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
[System.Xml.Serialization.XmlElementAttribute("Second", typeof(MySecondObject),
Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public object MyObject { get; set; }
}
public class MyFirstObject
{
public string theFirstObjectString { get; set; }
}
public class MySecondObject
{
public string theSecondObjectString { get; set; }
}
这个 class 通过使用 XmlElementAttribute 和 XmlSerializer 完美地序列化为 xml,但是当我尝试将它序列化为 Json(使用 Newtonsoft Json.Net)时,对象是未定义类型,无法反序列化。
有没有办法在 Json 属性中指定 XmlElementAttribute 以在序列化时获得相同的结果?
我想为序列化对象提供 Json 的使用,因为它的大小是 xml 的一半,但除非我能解决对象的序列化问题 属性问题。
提前致谢。
您必须创建自己的自定义序列化行为。在这里查看这个答案: on how to implement your own JsonConverter for Json.Net
在你的情况下,你可以做这样的事情来创建你的 json
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
MyTestXML myTestXml = (MyTestXML) value;
JObject jObject = JObject.FromObject(value);
JProperty prop = jObject.Children<JProperty>().First(p=>p.Name.Contains("MyObject"));
if (myTestXml.MyObject.GetType() == typeof (MyFirstObject))
{
prop.AddAfterSelf(new JProperty("First", JToken.FromObject(myTestXml.MyObject)));
prop.Remove();
jObject.WriteTo(writer);
}
else if (myTestXml.MyObject.GetType() == typeof (MySecondObject))
{
prop.AddAfterSelf(new JProperty("Second", JToken.FromObject(myTestXml.MyObject)));
prop.Remove();
jObject.WriteTo(writer);
}
}
反序列化时类似这样的事情
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
MyTestXML myTestXml = new MyTestXML();
serializer.Populate(jo.CreateReader(), myTestXml);
object myObject = null;
if (jo["First"] != null)
{
myObject = new MyFirstObject { TheFirstObjectString = jo["First"].SelectToken(@"TheFirstObjectString").Value<string>() };
}
if (jo["Second"] != null)
{
myObject = new MySecondObject { TheSecondObjectString = jo["Second"].SelectToken(@"TheSecondObjectString").Value<string>() };
}
myTestXml.MyObject = myObject;
return myTestXml;
}
要使用它,您需要在 serializing/deserializing 时提供 JsonConverter
,如下所示:
var settings = new JsonSerializerSettings();
settings.Converters.Add(new MyTextXmlJsonConverter());
var a = JsonConvert.SerializeObject(myTestXml, settings);
希望这就是您要找的
另一种选择是创建一个自定义合同解析器,它允许您检测应用了哪个 xml 属性。然后,如果需要特定输出,您可以在 属性 上应用自定义 JsonConverter。
public class CustomContractResolver : DefaultContractResolver
{
private readonly JsonMediaTypeFormatter formatter;
public CustomContractResolver(JsonMediaTypeFormatter formatter)
{
this.formatter = formatter;
}
public JsonMediaTypeFormatter Formatter
{
[DebuggerStepThrough]
get { return this.formatter; }
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
this.ConfigureProperty(member, property);
return property;
}
private void ConfigureProperty(MemberInfo member, JsonProperty property)
{
if (Attribute.IsDefined(member, typeof(XmlElementAttribute), true))
{
var attribute = member.CustomAttributes.Where(x => x.AttributeType == typeof(XmlElementAttribute)).First();
// do something with your attribute here like apply a converter
property.Converter = new XmlAttributeJsonConverter();
}
}
}
我有一个 class 需要序列化以传递给另一个系统。
class 包含一个定义为对象的 属性,因为对象将包含的 class 类型在运行时可能会有所不同。
我的 classes 看起来像这个简化的模型;
public class MyTestXML
{
public string String1 { get; set; }
public string String2 { get; set; }
[System.Xml.Serialization.XmlElementAttribute("First", typeof(MyFirstObject),
Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
[System.Xml.Serialization.XmlElementAttribute("Second", typeof(MySecondObject),
Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public object MyObject { get; set; }
}
public class MyFirstObject
{
public string theFirstObjectString { get; set; }
}
public class MySecondObject
{
public string theSecondObjectString { get; set; }
}
这个 class 通过使用 XmlElementAttribute 和 XmlSerializer 完美地序列化为 xml,但是当我尝试将它序列化为 Json(使用 Newtonsoft Json.Net)时,对象是未定义类型,无法反序列化。
有没有办法在 Json 属性中指定 XmlElementAttribute 以在序列化时获得相同的结果?
我想为序列化对象提供 Json 的使用,因为它的大小是 xml 的一半,但除非我能解决对象的序列化问题 属性问题。
提前致谢。
您必须创建自己的自定义序列化行为。在这里查看这个答案: on how to implement your own JsonConverter for Json.Net
在你的情况下,你可以做这样的事情来创建你的 json
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
MyTestXML myTestXml = (MyTestXML) value;
JObject jObject = JObject.FromObject(value);
JProperty prop = jObject.Children<JProperty>().First(p=>p.Name.Contains("MyObject"));
if (myTestXml.MyObject.GetType() == typeof (MyFirstObject))
{
prop.AddAfterSelf(new JProperty("First", JToken.FromObject(myTestXml.MyObject)));
prop.Remove();
jObject.WriteTo(writer);
}
else if (myTestXml.MyObject.GetType() == typeof (MySecondObject))
{
prop.AddAfterSelf(new JProperty("Second", JToken.FromObject(myTestXml.MyObject)));
prop.Remove();
jObject.WriteTo(writer);
}
}
反序列化时类似这样的事情
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
MyTestXML myTestXml = new MyTestXML();
serializer.Populate(jo.CreateReader(), myTestXml);
object myObject = null;
if (jo["First"] != null)
{
myObject = new MyFirstObject { TheFirstObjectString = jo["First"].SelectToken(@"TheFirstObjectString").Value<string>() };
}
if (jo["Second"] != null)
{
myObject = new MySecondObject { TheSecondObjectString = jo["Second"].SelectToken(@"TheSecondObjectString").Value<string>() };
}
myTestXml.MyObject = myObject;
return myTestXml;
}
要使用它,您需要在 serializing/deserializing 时提供 JsonConverter
,如下所示:
var settings = new JsonSerializerSettings();
settings.Converters.Add(new MyTextXmlJsonConverter());
var a = JsonConvert.SerializeObject(myTestXml, settings);
希望这就是您要找的
另一种选择是创建一个自定义合同解析器,它允许您检测应用了哪个 xml 属性。然后,如果需要特定输出,您可以在 属性 上应用自定义 JsonConverter。
public class CustomContractResolver : DefaultContractResolver
{
private readonly JsonMediaTypeFormatter formatter;
public CustomContractResolver(JsonMediaTypeFormatter formatter)
{
this.formatter = formatter;
}
public JsonMediaTypeFormatter Formatter
{
[DebuggerStepThrough]
get { return this.formatter; }
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
this.ConfigureProperty(member, property);
return property;
}
private void ConfigureProperty(MemberInfo member, JsonProperty property)
{
if (Attribute.IsDefined(member, typeof(XmlElementAttribute), true))
{
var attribute = member.CustomAttributes.Where(x => x.AttributeType == typeof(XmlElementAttribute)).First();
// do something with your attribute here like apply a converter
property.Converter = new XmlAttributeJsonConverter();
}
}
}