不使用属性将一个对象序列化为XML

3

是否有可能在不指定序列化属性的情况下控制XmlSerializer/DataContractSerializer的行为?

更具体地说,我想控制序列化(XmlIgnore、自定义属性名称等),但不希望装饰我的属性。

使用案例:

  • 已存在的大型类,我不想用序列化属性污染它们
  • 对于没有源代码的类进行序列化
  • 从使用XmlSerializer转换为使用DataContractSerializer或JSON而不更改类代码

例如,如何在不取消注释属性的情况下对以下内容进行序列化:

// [Serializable]
public MyClass
{
    // [XmlIgnore] - The following property should not be serialized, without uncommenting this line
    public int DontSerializeMeEvenThoughImPublic { get; set; }

    // [XmlAttribute("another_name")] - should be serialized as 'another_name', not 'SerializeMeAsXmlAttribute'
    public double SerializeMeAsXmlAttribute { get; set; }

    // [DataMember] - should be included
    private string IWantToBeSerializedButDontDecorateMeWithDataMember { get; set; }
}

你尝试过不使用属性进行序列化吗? - Renatas M.
1
你应该能够在没有属性的情况下顺利序列化,但是你不能控制输出。 - Ben Robinson
它是否应该遵循您示例中未注释的属性?如果不是,请将其删除。 - Patrick Hofman
@BenRobinson - 这是不正确的。例如,DontSerializeMeEvenThoughImPublic 将被序列化,尽管它应该被忽略。 - bavaza
@bavaza,就像我说的“你无法控制输出”。 - Ben Robinson
@BenRobinson - 哦,好的。 - bavaza
3个回答

5
您无法(优雅地)实现它。修改 XmlSerializer 序列化类的方式唯一的方法是使用属性(顺便说一下,SerializableAttribute 不是必需的)。DataContractSerializer 更糟糕。
一种可能的解决方案是创建中间类进行 XML 序列化/反序列化,并使用 Automapper 将数据复制到“真实”类和中介之间。 我使用这种方法将前端 XML 序列化问题保持在我的业务逻辑数据类型之外。

强烈推荐Automapper,这是一个非常棒的库,点赞! - bavaza

3

我知道这是一个老问题,但对于XmlSerializer部分,有趣的是没有人建议使用属性覆盖。

虽然不能解决私有属性,但据我所知,你也不能用属性来做到这一点,所以唯一的路线就是IXmlSerializable接口。

但是,通过添加属性,你可以像覆盖一样实现想要的更改。

以下内容应该可以实现注释掉的XmlAttributes所反映的更改要求:

public class Program
{
    public static void Main()
    {
        XmlAttributeOverrides overrides = new XmlAttributeOverrides();
        overrides.Add(typeof(MyClass), "DontSerializeMeEvenThoughImPublic", new XmlAttributes { XmlIgnore = true });
        overrides.Add(typeof(MyClass), "SerializeMeAsXmlAttribute", new XmlAttributes { XmlAttribute = new XmlAttributeAttribute("another_name") });
        XmlSerializer serializer = new XmlSerializer(typeof(MyClass), overrides);
        using (var writer = new StringWriter())
        {
            serializer.Serialize(writer, new MyClass());
            Console.WriteLine(writer.ToString());
        }
    }
}

2

使用 XmlSerializer 进行序列化应该可以不使用属性。


如果没有属性,你如何忽略问题中的第一个属性? - Patrick Hofman
1
我猜如果没有属性,这将是不可能的。另一方面,这会有害吗?如果您无法更改所涉及的类,则您的可能性会受到一定限制。这有点取决于总体目标。 - Codor
我将无法控制序列化。例如,即使应该被忽略,“DontSerializeMeEvenThoughImPublic”也会被序列化。 - bavaza
一种可能的方法是创建一个适配器类,该类具有相同的数据成员,并且可以从/向先前存在的类型进行赋值。然而,这种方法不太优雅,往往难以维护。 - Codor
@PatrickHofman 您可以使用XmlAttributeOverrides,但据我所知,它们无法解决私有属性的问题... - Jens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接