La siguiente clase se puede utilizar para serializar (y deserializar) partes del árbol de objetos en XML y luego en JSON.
Uso
[JsonObject]
public class ClassToSerializeWithJson
{
[JsonProperty]
public TypeThatIsJsonSerializable PropertySerializedWithJsonSerializer {get; set; }
[JsonProperty]
[JsonConverter(typeof(JsonXmlConverter<TypeThatIsXmlSerializable>))]
public TypeThatIsXmlSerializable PropertySerializedWithCustomSerializer {get; set; }
}
clase JsonXmlConverter
public class JsonXmlConverter<TType> : JsonConverter where TType : class
{
private static readonly XmlSerializer xmlSerializer = new XmlSerializer(typeof(TType));
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var xml = ToXml(value as TType);
using (var stream = new StringReader(xml))
{
var xDoc = XDocument.Load(stream);
var json = JsonConvert.SerializeXNode(xDoc);
writer.WriteRawValue(json);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
// consume the 'null' token to set the reader in the correct state
JToken.Load(reader);
return null;
}
var jObj = JObject.Load(reader);
var json = jObj.ToString();
var xDoc = JsonConvert.DeserializeXNode(json);
var xml = xDoc.ToString();
return FromXml(xml);
}
public override bool CanRead => true;
public override bool CanConvert(Type objectType) => objectType == typeof(TType);
private static TType FromXml(string xmlString)
{
using (StringReader reader = new StringReader(xmlString))
return (TType)xmlSerializer.Deserialize(reader);
}
private static string ToXml(TType obj)
{
using (StringWriter writer = new StringWriter())
using (XmlWriter xmlWriter = XmlWriter.Create(writer))
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add(String.Empty, String.Empty);
xmlSerializer.Serialize(xmlWriter, obj, ns);
return writer.ToString();
}
}
}
Newtonsoft Json.Net http://james.newtonking.com/projects/json/help/SerializationAttributes.html "también busca la DataContract y atributos DataMember la hora de determinar la forma en JSON es que ser serializado y deserializado". ¿Alguien sabe si XmlElementAttributes et al son interoperables con DataContractAttributes? –
Un serializador podría implementar la serialización de ambos Atributos, pero supongo que depende del serializador ... (también vea http://social.msdn.microsoft.com/Forums/en/wcf/thread/be796bd0-2502-4bd3- 96d9-60bf7d68930d) – hangy
He escrito un pequeño parche para Json.Net que permite que DefaultContractResolver funcione con atributos Xml. Funciona para el ejemplo simple anterior, pero necesito escribir algunas pruebas más para ejemplos más complejos (tipo anónimo, etc.) antes de liberarlo. –