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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18242320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:38:27  来源:igfitidea点击:

Ignore a property during xml serialization but not during deserialization

c#.netxml-serializationjson.netdeserialization

提问by Manoj

In C#, how can I make XmlSerializer ignore a property during serialization but not during deserialization? (Or how do I do the same with Json.net?)

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

To prevent a property from being serialized, you can add the XmlIgnoreattribute:

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

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

This will cause the <FooBar>tag to be omitted during serialization.

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

However, this also means that the <FooBar>tag will be ignored during deserialization.

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

In my case, I accept an array of items from user in the request, and for each item user can specify an action property if they want to add, modify or delete the item. I want to use the same model object for GET list calls, and don't want to return this action property. I expect this would be a pretty common case.

就我而言,我在请求中接受来自用户的一组项目,如果用户想要添加、修改或删除项目,则可以为每个项目指定一个操作属性。我想对 GET 列表调用使用相同的模型对象,并且不想返回此操作属性。我预计这将是一个非常普遍的案例。

Another use case: say you have a circle object

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

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

and you modify it to add a diameter property

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

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

You may want to serialize only the diameter, but still be able to deserialize xml files in the old format that contain only the radius.

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

I did my research and didn't find anything, hence this question

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

Solution: I figured out the solution. I can add a ShouldSerialize property which always return false, details at this MSDN documentation

解决方案:我想出了解决方案。我可以添加一个 ShouldSerialize 属性,该属性始终返回 false,此 MSDN 文档中的详细信息

(this solution could be added as an actual answer if this question is reopened)

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

采纳答案by fcuesta

If you want to ignore the element at serialization with XmlSerializer, you can use XmlAttributeOverrides:

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

回答by HugoRune

This is the solution outlined by Manoj:

这是 Manoj 概述的解决方案:

If you want to suppress serialization of a specific property Foo, but still be able to deserialize it, you can add a method public bool ShouldSerializeFoo()that always returns false.

如果您想抑制特定属性的序列化Foo,但仍然能够反序列化它,您可以添加一个public bool ShouldSerializeFoo()始终返回 false的方法。

Example:

例子:

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

This will cause the Radius to not be serialized, but still allow it to be deserialized.

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

This method has to be public for the XMLSerializer to find it, so in order to avoid polluting the namespace you can add the EditorBrowsableattribute to hide it from the IDE. Unfortunately this hiding only works if the assembly is referenced as a DLL in your current project, but not if you edit the actual project with this code.

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