Search code examples
c#serializationattributes

How to solve "Both use the XML type name X, use XML attributes to specify a unique XML name and/or namespace for the type"?


I have the following enum definitions...

namespace ItemTable
{
  public enum DisplayMode
  {
    Tiles,
    Default
  }
}

namespace EffectiveItemPermissionTable
{
  public enum DisplayMode
  {
    Tree,
    FullPaths
  }
}

...and then i have the following classes...

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

...and when i try to serialize an instance of UISettings with...

System.Xml.Serialization.XmlSerializer lSerializer =
  new System.Xml.Serialization.XmlSerializer(typeof(UISettings));

...i get the following error:

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.

I have tried to use XmlType attribubtes and all sorts of solutions posted on the web but nothing works. The XML type name is always TableOfDisplayMode as mentioned in the error.

The only solution right now is to rename one of the enums, e.g. to DisplayMode_ but I find that rather ugly.


Solution

  • You need to provide the Namespace by using the XmlElement attribute on the properties of your UISettings class:

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

    When applied here this will be your serialized output:

    <?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>
    

    Alternatively, and maybe cleaner, you can provide the Namespace on the types:

    [XmlType(Namespace="Item")]
    public class ItemTable : Table<ItemTableNS.DisplayMode>
    { }
    
    [XmlType(Namespace = "Permission")]
    public class EffectiveItemPermissionTable : Table<EffectiveItemPermissionTableNS.DisplayMode>
    { }
    

    This will serialize as:

    <?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>