我有一个.Net对象,我已经将其序列化为Xml并使用Xml属性进行修饰。我现在想将同一个对象序列化为Json,最好使用Newtonsoft Json.Net库。
我想直接从内存中的.Net对象转到Json字符串(不先串行化为Xml)。我不希望在类中添加任何Json属性,而是希望Json序列化程序使用现有的Xml属性。
public class world{
[XmlIgnore]
public int ignoreMe{ get; }
[XmlElement("foo")]
public int bar{ get; }
[XmlElement("marco")]
public int polo{ get; }
}
变为
{
"foo":0,
"marco":0
}
答案 0 :(得分:10)
使用[JsonProperty(PropertyName="foo")]
属性并设置PropertyName
。
答案 1 :(得分:5)
原来这不是Newtonsoft Json.Net库的现有功能。我已经编写了一个补丁并将其上传到Json.Net issue tracker(已存档的链接here):
这允许以下内容:
答案 2 :(得分:4)
您可以创建一个自定义合约解析程序,它允许您对属性进行调整,并将它们设置为忽略XmlIgnoreAttribute的设置位置。
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(XmlIgnoreAttribute), true))
{
property.Ignored = true;
}
}
}
您可以使用在序列化对象时通过设置JsonSerializerSettings的ContractResolver属性来应用此自定义解析器
https://www.newtonsoft.com/json/help/html/ContractResolver.htm
string json =
JsonConvert.SerializeObject(
product, // this is your object that has xml attributes on it that you want ignored
Formatting.Indented,
new JsonSerializerSettings { ContractResolver = new CustomResolver() }
);
如果您正在使用WebApi,则可以全局设置以应用于所有合同。
var config = GlobalConfiguration.Configuration;
var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.ContractResolver = new CustomContractResolver();
答案 3 :(得分:0)
下面的类可用于将对象树的部分序列化(和反序列化)为XML,然后再序列化为JSON。
<强>用法强>
[JsonObject]
public class ClassToSerializeWithJson
{
[JsonProperty]
public TypeThatIsJsonSerializable PropertySerializedWithJsonSerializer {get; set; }
[JsonProperty]
[JsonConverter(typeof(JsonXmlConverter<TypeThatIsXmlSerializable>))]
public TypeThatIsXmlSerializable PropertySerializedWithCustomSerializer {get; set; }
}
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();
}
}
}