我有以下枚举定义......
namespace ItemTable
{
public enum DisplayMode
{
Tiles,
Default
}
}
namespace EffectiveItemPermissionTable
{
public enum DisplayMode
{
Tree,
FullPaths
}
}
...然后我有以下课程......
public class Table<TDisplayMode>
where TDisplayMode: struct
{
// public
public TDisplayMode DisplayMode
{
get { return mDisplayMode; }
set { mDisplayMode = value; }
}
// private
private TDisplayMode mDisplayMode;
}
public class ItemTable : Table<ItemTable.DisplayMode>
{}
public class EffectiveItemPermissionTable : Table<EffectiveItemPermissionTable.DisplayMode>
{}
public class UISettings
{
public UISettings()
{
ItemTable = new ItemTable();
EffectiveItemPermissionTable = new EffectiveItemPermissionTable();
}
public ItemTable ItemTable { get; set; }
public EffectiveItemPermissionTable EffectiveItemPermissionTable { get; set; }
}
...当我尝试使用...
序列化UISettings实例时System.Xml.Serialization.XmlSerializer lSerializer =
new System.Xml.Serialization.XmlSerializer(typeof(UISettings));
...我收到以下错误:
Types 'UISettings.Table`1[EffectiveItemPermissionTable.DisplayMode]' and
'UISettings.Table`1[ItemTable.DisplayMode]' both use the XML type name,
'TableOfDisplayMode', from namespace ''.
Use XML attributes to specify a unique XML name and/or namespace for the type.
我曾尝试使用XmlType attribubtes和网上发布的各种解决方案,但没有任何效果。 XML类型名称始终为TableOfDisplayMode
,如错误中所述。
现在唯一的解决方案是重命名其中一个枚举,例如:到DisplayMode_
,但我觉得相当难看。
答案 0 :(得分:8)
您需要使用XmlElement
类属性的UISettings
属性提供Namespace:
public class UISettings
{
public UISettings()
{
ItemTable = new ItemTable();
EffectiveItemPermissionTable = new EffectiveItemPermissionTable();
}
[XmlElement(Namespace = "Item")]
public ItemTable ItemTable { get; set; }
[XmlElement(Namespace = "Permissions")]
public EffectiveItemPermissionTable EffectiveItemPermissionTable { get; set; }
}
在此处应用时,这将是您的序列化输出:
<?xml version="1.0" encoding="utf-16"?>
<UISettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ItemTable xmlns="Item">
<DisplayMode>Tiles</DisplayMode>
</ItemTable>
<EffectiveItemPermissionTable xmlns="Permissions">
<DisplayMode>FullPaths</DisplayMode>
</EffectiveItemPermissionTable>
</UISettings>
或者,也许更干净,您可以在类型上提供命名空间:
[XmlType(Namespace="Item")]
public class ItemTable : Table<ItemTableNS.DisplayMode>
{ }
[XmlType(Namespace = "Permission")]
public class EffectiveItemPermissionTable : Table<EffectiveItemPermissionTableNS.DisplayMode>
{ }
这将序列化为:
<?xml version="1.0" encoding="utf-16"?>
<UISettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ItemTable>
<DisplayMode xmlns="Item">Tiles</DisplayMode>
</ItemTable>
<EffectiveItemPermissionTable>
<DisplayMode xmlns="Permission">FullPaths</DisplayMode>
</EffectiveItemPermissionTable>
</UISettings>
答案 1 :(得分:5)
我意识到这个答案可能对OP来说太迟了,但有一种方法可以在不使用命名空间的情况下做到这一点,所以我将在这里留下答案,以防有人跟我走后需要解决方案。
问题的原因是XmlSerializer
为X<Y>
类型命名的方式是为其命名XOfY
。因此,当您有两种类型都来自Table<TDisplayMode>
时,您会收到该错误,因为尽管实际上使用了不同的枚举,但它们都会在内部被称为TableOfDisplayMode
。
这是因为ItemTable
和EffectiveItemPermissionTable
实际上不从同一类型继承!一个来自Table<ItemTable.DisplayMode>
,另一个来自Table<EffectiveItemPermissionTable.DisplayMode>
。并不是说这仅限于继承;如果你试图直接在同一个XML对象图中使用它们,你也会遇到同样的问题。
现在,对于这个问题的非通用对应物,你只需在这两种类型上点击[XmlType]
,并将其称为一天。但你不能在这里做到这一点。虽然Table<ItemTable.DisplayMode>
和Table<EffectiveItemPermissionTable.DisplayMode>
是不同的类型,但它们共享相同的类定义,因此尝试使用[XmlType]
时,您会给它们一个不同的名称,但名称仍然相同。 / p>
那你能做什么? XmlAttributeOverrides
救援!它允许您覆盖XmlSerializer
为封闭泛型类型提供的名称,这意味着您最终可以为Table<ItemTable.DisplayMode>
和Table<EffectiveItemPermissionTable.DisplayMode>
指定其他名称:
var xmlOverrides = new XmlAttributeOverrides();
var xmlAttribs = new XmlAttributes();
xmlAttribs.XmlType = new XmlTypeAttribute("TableOfItemTableDisplayMode");
xmlOverrides.Add(typeof(Table<ItemTable.DisplayMode>), xmlAttribs);
xmlAttribs = new XmlAttributes();
xmlAttribs.XmlType = new XmlTypeAttribute("TableOfEffectiveItemPermissionTableDisplayMode");
xmlOverrides.Add(typeof(Table<EffectiveItemPermissionTable.DisplayMode>), xmlAttribs);
System.Xml.Serialization.XmlSerializer lSerializer =
new System.Xml.Serialization.XmlSerializer(typeof(UISettings), xmlOverrides);
瞧!现在假设你还为你的[XmlType]
枚举添加了DisplayMode
不同的名称,这样他们的名字也不会发生冲突,你就可以自己设置工作了!