ViR*_*iTy 11 c# serialization attributes
我有以下枚举定义......
namespace ItemTable
{
public enum DisplayMode
{
Tiles,
Default
}
}
namespace EffectiveItemPermissionTable
{
public enum DisplayMode
{
Tree,
FullPaths
}
}
Run Code Online (Sandbox Code Playgroud)
......然后我有以下课程......
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; }
}
Run Code Online (Sandbox Code Playgroud)
...当我尝试用...序列化UISettings的实例时...
System.Xml.Serialization.XmlSerializer lSerializer =
new System.Xml.Serialization.XmlSerializer(typeof(UISettings));
Run Code Online (Sandbox Code Playgroud)
...我收到以下错误:
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.
Run Code Online (Sandbox Code Playgroud)
我曾尝试使用XmlType attribubtes和网上发布的各种解决方案,但没有任何效果.XML类型名称始终TableOfDisplayMode如错误中所述.
现在唯一的解决方案是重命名其中一个枚举,例如,DisplayMode_但我觉得相当难看.
您需要使用类的属性上的属性来提供命名空间:XmlElementUISettings
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; }
}
Run Code Online (Sandbox Code Playgroud)
在这里应用时,这将是您的序列化输出:
<?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>
Run Code Online (Sandbox Code Playgroud)
或者,也许更干净,您可以在类型上提供命名空间:
[XmlType(Namespace="Item")]
public class ItemTable : Table<ItemTableNS.DisplayMode>
{ }
[XmlType(Namespace = "Permission")]
public class EffectiveItemPermissionTable : Table<EffectiveItemPermissionTableNS.DisplayMode>
{ }
Run Code Online (Sandbox Code Playgroud)
这将序列化为:
<?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>
Run Code Online (Sandbox Code Playgroud)
我意识到这个答案对于OP来说可能为时已晚,但是有一种方法可以不使用名称空间,因此我将在这里留下一个答案,以防有人追随我并需要解决方案。
该问题是由以下事实引起的:XmlSerializer命名类型的方式X<Y>是通过给它命名XOfY。因此,当您有两个都源自的类型时Table<TDisplayMode>,您会得到该错误,因为TableOfDisplayMode尽管实际上使用了不同的枚举,但它们在内部都被称为。
这是因为ItemTable和EffectiveItemPermissionTable实际上不是从同一类型继承!一个从继承,Table<ItemTable.DisplayMode>另一个从继承Table<EffectiveItemPermissionTable.DisplayMode>。这不仅仅限于继承。如果您还尝试在同一XML对象图中直接使用它们,则会遇到相同的问题。
现在,对于该问题的非泛型对应物,您只需[XmlType]对这两种类型打点,然后将其命名为“ day”。但是您不能在这里这样做。虽然Table<ItemTable.DisplayMode>和Table<EffectiveItemPermissionTable.DisplayMode>是不同的类型,但是它们共享相同的类定义,因此通过尝试使用[XmlType],可以为它们指定不同的名称,但仍使用相同的名称。
所以,你可以做什么?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);
Run Code Online (Sandbox Code Playgroud)
和瞧!现在假设您还[XmlType]为DisplayMode枚举使用了不同的名称,以使它们的名称也不会冲突,那么您自己就可以正常工作了!
| 归档时间: |
|
| 查看次数: |
6595 次 |
| 最近记录: |