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

时间:2013-08-14 21:06:47

标签: c# .net xml-serialization json.net deserialization

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

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

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

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

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

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

另一个用例: 说你有一个圆形物体

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

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

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

解决方案:我找到了解决方案。我可以在this MSDN documentation

添加一个始终返回false的详细信息的ShouldSerialize属性

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

2 个答案:

答案 0 :(得分:28)

这是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时,此隐藏才有效,但如果使用此代码编辑实际项目则不行。

答案 1 :(得分:27)

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