在xml序列化期间忽略属性,但在反序列化期间不忽略

Man*_*noj 49 .net c# xml-serialization json.net deserialization

在C#中,如何在序列化期间使XmlSerializer忽略属性,而不是在反序列化期间忽略属性?(或者我如何对Json.net做同样的事情?)

要阻止属性序列化,可以添加XmlIgnore属性:

[XmlIgnore]
public int FooBar {get;set;}
Run Code Online (Sandbox Code Playgroud)

这将导致<FooBar>在序列化期间省略标记.

但是,这也意味着<FooBar>在反序列化期间将忽略标记.

在我的例子中,我在请求中接受来自用户的一系列项目,并且对于每个项目,如果用户想要添加,修改或删除项目,则可以指定动作属性.我想为GET列表调用使用相同的模型对象,并且不想返回此action属性.我希望这是一个很常见的情况.

另一个用例:说你有一个圆形对象

public class Circle
{
    public double Radius { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并修改它以添加直径属性

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }
}
Run Code Online (Sandbox Code Playgroud)

您可能只想序列化直径,但仍能够以旧格式反序列化仅包含半径的xml文件.

我做了我的研究并没有找到任何东西,因此这个问题

解决方案:我找到了解决方案.我可以在此MSDN文档中添加一个始终返回false的ShouldSerialize属性

(如果重新打开此问题,可以将此解决方案添加为实际答案)

Hug*_*une 33

这是Manoj概述的解决方案:

如果要禁止特定属性的序列化Foo,但仍能够对其进行反序列化,则可以添加public bool ShouldSerializeFoo()始终返回false 的方法.

例:

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public bool ShouldSerializeRadius() {return false;}
}
Run Code Online (Sandbox Code Playgroud)

这将导致Radius不被序列化,但仍然允许它反序列化.

此方法必须公开才能让XMLSerializer找到它,因此为了避免污染命名空间,您可以添加该EditorBrowsable属性以将其隐藏在IDE中.不幸的是,只有在当前项目中将程序集引用为DLL时,此隐藏才有效,但如果使用此代码编辑实际项目则不行.

  • 这非常有用。 (2认同)

fcu*_*sta 31

如果要在XmlSerializer的序列化中忽略元素,可以使用XmlAttributeOverrides:

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("YourElementName"));
overrides.Add(typeof(YourClass), "YourElementName", attribs);

XmlSerializer ser = new XmlSerializer(typeof(YourClass), overrides);
ser.Serialize(...
Run Code Online (Sandbox Code Playgroud)

  • 序列化时使用:XmlSerializer ser = new XmlSerializer(typeof(YourClass),覆盖); 反序列化时使用XmlSerializer ser = new XmlSerializer(typeof(YourClass)); 没有覆盖参数 (5认同)
  • 使用覆盖构建的序列化器应该静态缓存以避免内存泄漏;有关详细信息,请参阅[使用 StreamReader 和 XmlSerializer 的内存泄漏](/sf/ask/1672800181/)。 (2认同)