如何强制使用xsi:type属性? [英] How can I force the use of an xsi:type attribute?

查看:597
本文介绍了如何强制使用xsi:type属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何强制.NET的XmlSerializer向 FooClass xsi:type = FooClass > ?

How can I force .NET's XmlSerializer to add an xsi:type="FooClass" to a member/node of type FooClass?

该方案是当前发布的应用程序,其中在v.1中:

The scenario is a currently-released app, where in v.1 :


  • FooClass继承了FooBaseClass

  • FooPropertyA在FooBaseClass

  • FooPropertyB在FooClass

  • FooBaseClass装饰有[XmlInclude(typeof(FooClass))]

  • BazClass具有类型为FooBaseClass的成员Foo

  • 所有Baz.Foo集都是FooClass实例

  • Baz.Foo的所有用法都期望FooPropertyB(以及FooClass实例vs FooBaseClass)

  • FooClass inherits FooBaseClass
  • FooPropertyA is on FooBaseClass
  • FooPropertyB is on FooClass
  • FooBaseClass is decorated with [XmlInclude(typeof(FooClass))]
  • BazClass has member Foo of type FooBaseClass
  • All sets of Baz.Foo are to a FooClass instance
  • All usages of Baz.Foo expect FooPropertyB (and so a FooClass instance vs FooBaseClass)

目标:完全删除FooBaseClass,将FooBaseClass的成员推入FooClass,同时保持向后串行兼容性

The goal: Remove FooBaseClass entirely, pushing FooBaseClass's members up into FooClass, while maintaining backward serialization compatibility

问题:然后我丢失了Baz.Foo序列化中的xsi:type = FooClass属性。

换句话说,就是XmlSerializer.Serialize输出

In other words the XmlSerializer.Serialize output of

public class BazClass
{
    public BazClass()
    {
        Foo = new FooClass { A = 5, B = "Hello" };
    }
    public FooClass Foo { get; set; }
}

public class FooClass
{
    public int FooPropertyA { get; set; }
    public string FooPropertyB { get; set; }
}

需要成为

<Baz>
    <Foo xsi:type="FooClass">
        <FooPropertyA>Hello</FooPropertyA>
        <FooPropertyB>5</FooPropertyB>
    </Foo>
</Baz>

删除FooBasClass很容易,但是XmlSerializer不再将xsi:type = FooClass放在Baz / Foo,因此v.1 XmlSerializer.Deserialize实例化一个FooBaseClass实例,而不设置FooPropertyB,并将其分配给父Baz实例的Foo属性。因此,任何检查Baz.Foo是FooClass还是直接强制转换的代码都会失败。

Removing FooBasClass is easy, but then XmlSerializer no longer places xsi:type="FooClass" on Baz/Foo, and so v.1 XmlSerializer.Deserialize instantiates a FooBaseClass instance, not setting FooPropertyB, and assigns it to the Foo property of the parent Baz instance. Thus, any code which checks whether Baz.Foo is FooClass, or casts directly, fails.

xsi:type属性自动放置在v.1代码中,该代码是

The xsi:type attribute was placed automatically in the v.1 code which was

public class BazClass
{
    public BazClass()
    {
        Foo = new FooClass { A = 5, B = "Hello" };
    }
    public FooBaseClass Foo { get; set; }
}

public class FooClass : FooBaseClass
{
    public string FooPropertyB { get; set; }
}

[XmlInclude(typeof(FooClass))]    
public class FooBaseClass
{
    public int FooPropertyA { get; set; }
}

我认为简短的答案是您不能-至少不能无需实现I(Xml)Serializable或编写自定义序列化代码。但是,我愿意接受好的建议。同时,我在下面实现了一个解决方法 hack,希望有一些更优雅的方法,或者至少可以允许我以某种方式完全删除FooBaseClass。

I think the short answer is that you can't - at least not without implementing I(Xml)Serializable or writing custom serialization code. However, I'm open to good suggestions. Meanwhile I have implemented a workaround hack below, and am hoping for something more elegant, or that at least allows me somehow to remove FooBaseClass entirely.

BazClass
{
    [XmlElement("Foo")]
    public FooBaseClass XmlFoo { get { return Foo; } set { Foo = (StartPicture)value; } }

    [XmlIgnore]
    public FooClass Foo { get; set; }
}    

FooClass : FooBaseClass
{
    public int FooPropertyB { get; set; }
    public string FooPropertyA { get; set; }
}

[XmlInclude("FooClass")]
FooBaseClass
{
}


推荐答案

XmlSerializer 有时可能非常愚蠢而简单。在这种情况下对您有利。只需手动将其放到那里即可。

XmlSerializer can be pretty dumb and straightforward at times, which works to your advantage in this case. Just put it there manually:

public class FooClass
{
    public int FooPropertyA { get; set; }
    public string FooPropertyB { get; set; }

    [XmlAttribute("type", Namespace="http://www.w3.org/2001/XMLSchema-instance")]
    public string XsiType
    {
        get { return "Foo"; }
        set { }
    }
}

这篇关于如何强制使用xsi:type属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆