在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文档
(如果重新打开此问题,此解决方案可以作为实际答案添加)
这是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(...