将.Net对象序列化为json,使用xml属性进行控制

Iai*_*oat 14 c# xml-serialization json.net

我有一个.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; }
}
Run Code Online (Sandbox Code Playgroud)

{
  "foo":0,
  "marco":0
}
Run Code Online (Sandbox Code Playgroud)

Ali*_*tad 10

使用[JsonProperty(PropertyName="foo")]属性并设置PropertyName.


Iai*_*oat 6

事实证明这不是Newtonsoft Json.Net库的现有功能.我写了一个补丁并将其上传到Json.Net问题跟踪器(此处存档链接):

这允许以下内容:

  • XmlIgnore就像JsonIgnore一样工作.
  • XmlElementAttribute.ElementName将更改Json属性名称.
  • XmlType.AnonymousType将禁止将对象打印到Json(XmlContractResolver.SuppressAnonymousType属性改变这种行为)这有点hacky,因为我必须像以前一样学习Json.Net的内部.

  • 万一有人碰到这个,它并没有成为Json.NET的源头.我很想知道任何其他解决方案. (10认同)

Den*_*her 5

您可以创建一个自定义合同解析器,它允许您对属性进行调整并将它们设置为忽略设置 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;
        }            
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在序列化对象时通过设置 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() }
        );
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 WebApi,则可以将其全局设置为适用于所有合同。

var config = GlobalConfiguration.Configuration;
var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.ContractResolver = new CustomContractResolver();
Run Code Online (Sandbox Code Playgroud)