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

本文关键字:反序列化 属性 序列化 xml | 更新日期: 2023-09-27 18:27:47

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

为了防止属性被序列化,可以添加XmlIgnore属性:

[XmlIgnore]
public int FooBar {get;set;}

这将导致在序列化过程中省略<FooBar>标记。

但是,这也意味着<FooBar>标记将在反序列化过程中被忽略。

在我的情况下,我在请求中接受来自用户的一组项,如果用户想添加、修改或删除该项,则可以为每个项指定一个操作属性。我想对GET列表调用使用相同的模型对象,并且不想返回此操作属性。我想这将是一个非常常见的情况。

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

public class Circle
{
    public double Radius { get; set; }
}

然后修改它以添加直径属性

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

您可能只想序列化diameter,但仍然可以反序列化只包含radius的旧格式的xml文件。

我做了研究,没有发现任何东西,因此这个问题

解决方案:我找到了解决方案。我可以添加ShouldSerialize属性,该属性总是返回false,详细信息请参阅MSDN文档

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

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

这是Manoj:概述的解决方案

如果您希望抑制特定属性Foo的序列化,但仍然能够对其进行反序列化,则可以添加一个始终返回false的方法public bool ShouldSerializeFoo()

示例:

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;}
}

这将导致Radius不被序列化,但仍允许对其进行反序列化。

这个方法必须是公共的,XMLSerializer才能找到它,所以为了避免污染命名空间,可以添加EditorBrowsable属性来向IDE隐藏它。不幸的是,只有当程序集在当前项目中被引用为DLL时,这种隐藏才有效,但如果使用此代码编辑实际项目,则无效。

如果要在使用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(...