2

我正在尝试从配置文件中序列化一些自定义设置。以下是我的设置:

<FavouriteTools>
        <favouriteTool PluginPlaceHolder="FavoriteTool1" PlugInName="Brightness"
          PlugInType="2D" PlugInAssemblyName="Micro.DigiMic.Plugins.AreaBasedOnBrightness.AreaBasedOnBrightnessPlugin"
          GUID="0000c03a-b891-4ebd-87d7-5fbc19073a1a" />
        <favouriteTool PluginPlaceHolder="FavoriteTool2" PlugInName="CircleArea"
          PlugInType="2D" PlugInAssemblyName="Micro.DigiMic.Plugins.CircleAreaPlugin.CircleAreaPlugin"
          GUID="0000c06a-b891-4ebd-87d7-5fbc19073a1a" />
        <favouriteTool PluginPlaceHolder="FavoriteTool3" PlugInName="Contour Area"
          PlugInType="2D" PlugInAssemblyName="Micro.DigiMic.Plugins.ContourAreaPlugin.ContourAreaPlugin"
          GUID="0000c11a-b891-4ebd-87d7-5fbc19073a1a" />         

但是在序列化它们时出现错误。这是我的课。

//FavouriteTools - Root Node
[Serializable]
[XmlType("FavoriteTools")]
[ConfigurationCollection(typeof(FavouriteTool), AddItemName = "favouriteTool", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class FavouriteToolsCollection
: ConfigurationElementCollection    
{
//Few plublic methods here
}

//favouriteTool -  Child node
[Serializable]
[XmlType("favouriteTool")]
public class FavouriteTool : ConfigurationElement
{
    /// <summary>
    /// Gets or sets value of Plugin PlaceHolder.
    /// </summary>
    /// <value>Text Color.</value> 
    [ConfigurationProperty("PluginPlaceHolder", IsRequired = false)]
    public string PlugPlaceHolder
    {
        get { return (string)base["PluginPlaceHolder"]; }
        set { base["PluginPlaceHolder"] = value; }
    }

//Few more properties like above
}

I am trying to serialize below class, but gets exception on below like

XmlSerializer xmlinf = new XmlSerializer(data.GetType());


`data` is `ExportUser`

[Serializable]
public class ExportUser
{

public bool IsMetric { get; set; }

[XmlArray("FavoriteTools")]
    [XmlArrayItem("favouriteTool")]
    public FavouriteToolsCollection FavoriteTools { get; set; }
 }  

我收到此错误 -There was an error reflecting type 'ExportUser'在内部异常中,错误显示 - There was an error reflecting type 'FavoriteTools'

有什么遗漏吗?

更新:

看到内部异常后,错误是

{"You must implement a default accessor on System.Configuration.ConfigurationLockCollection because it inherits from ICollection."}

There was an error reflecting type 'Zeiss.Micro.DigiMic.Application.FavouriteTool'.

但我在FavouriteToolsCollection课堂上确实有一个默认访问器:

public FavouriteTool this[int index]
    {
        get
        {
            return (FavouriteTool)BaseGet(index);
        }

        set
        {
            if (this.BaseGet(index) != null)
            {
                this.BaseRemoveAt(index);
            }

            this.BaseAdd(index, value);
        }
    }

还缺少什么?

4

1 回答 1

1

好的。我刚遇到这个。并使用包装器对象解决了它。

我所做的是为我想要序列化的东西创建一个简单的包装对象。我的情况是一个ConfigurationCollection。我对其进行序列化并创建几个适配器以从可序列化对象映射到实际对象,反之亦然。

using system.Xml.Serialization;

// This is an XML wrapper for FolderElement.
public class FolderAttributes
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlAttribute("Volume")]
    public string Volume { get; set; }
    [XmlAttribute("Path")]
    public string Path { get; set; }

    [XmlAttribute("Selected")]
    public bool Selected { get; set; }
    [XmlAttribute("Active")]
    public bool Active { get; set; }

    /// <summary>
    /// Factory Method.
    /// Create new instance of FolderAttributes from FolderElment.
    /// </summary>
    /// <param name="element"></param>
    /// <returns></returns>
    public static FolderAttributes FromElement(FolderElement element)
    {
        return new FolderAttributes()
        {
            Name = element.Name,
            Volume = element.VolumeLabel,
            Path = element.Path,
            Selected = element.Selected,
            Active = element.Active
        };

    }

    /// <summary>
    /// Convert this instance to a FolderElement.
    /// </summary>
    /// <returns></returns>
    public FolderElement ToElement()
    {
        return new FolderElement()
        {
            Name = Name,
            VolumeLabel = Volume,
            Path = Path,
            Selected = Selected,
            Active = Active
        };

    }
}
public class FolderElement : ConfigurationElement
{
    protected const string NameKey = "name";
    protected const string VolumeKey = "volume";
    protected const string PathKey = "path";
    protected const string selectedKey = "selected";
    protected const string activeKey = "active";

    [ConfigurationProperty(NameKey, DefaultValue = "", IsKey = true, IsRequired = true)]
    public string Name
    {
        get { return (string)base[NameKey]; }
        set { base[NameKey] = value; }
    }

    [ConfigurationProperty(VolumeKey, DefaultValue = "", IsKey = false, IsRequired = false)]
    public string VolumeLabel
    {
        get { return (string)base[VolumeKey]; }
        set { base[VolumeKey] = value; }
    }

    [ConfigurationProperty(PathKey, DefaultValue = "", IsKey = false, IsRequired = true)]
    public string Path
    {
        get { return (string)base[PathKey]; }
        set { base[PathKey] = value; }
    }

    [ConfigurationProperty(selectedKey, DefaultValue = "false", IsKey = false, IsRequired = false)]
    public bool Selected
    {
        get { return (bool)base[selectedKey]; }
        set { base[selectedKey] = value; }
    }

    [ConfigurationProperty(activeKey, DefaultValue = "true", IsKey = false, IsRequired = false)]
    public bool Active
    {
        get { return (bool)base[activeKey]; }
        set { base[activeKey] = value; }
    }
}

[ConfigurationCollection(typeof(FolderElement))]
public class FolderCollection : ConfigurationElementCollection
{
    internal const string _elementName = "elements";

    protected override string ElementName
    {
        get { return _elementName; }
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.AddRemoveClearMap; }
    }

    protected override bool IsElementName(string elementName)
    {
        return elementName.Equals(_elementName, StringComparison.InvariantCultureIgnoreCase);
    }

    public override bool IsReadOnly()
    {
        return false;
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new FolderElement();
    }

    /// <summary>
    /// Return key value for element.
    /// </summary>
    /// <param name="element"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((FolderElement)element).Name;
    }

    /// <summary>
    /// Default index property.
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public FolderElement this[int index]
    {
        get { return (FolderElement)BaseGet(index); }
    }


    /// <summary>
    /// Returns content element by name.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public FolderElement GetElementByName(string name)
    {
        return (FolderElement)BaseGet(name);
    }


    public IEnumerable<FolderElement> Elements
    {
        get
        {
            for (int index = 0; index < this.Count; index++) yield return (FolderElement)BaseGet(index);
        }
    }

    /// <summary>
    /// Add an element to the collection
    /// </summary>
    /// <param name="element"></param>
    public void AddElement(FolderElement element)
    {
        BaseAdd(element);
    }


}

public class FolderSection : ConfigurationSection
{

    // Attribute argument must be a constant expression.
    protected const string _elementsTag = "elements";

    [ConfigurationProperty(_elementsTag, Options = ConfigurationPropertyOptions.IsDefaultCollection)]
    public FolderCollection Elements
    {
        get { return ((FolderCollection)(base[_elementsTag])); }
        set { base[_elementsTag] = value; }
    }

    public void SaveElements(ConfigurationElementCollection elements, string path)
    {
        var container = new List<FolderAttributes>();

        foreach (FolderElement element in elements)
        {
            container.Add(FolderAttributes.FromElement(element));
        }

        // XmlHelper.SaveXml(container, path);
        SaveXml(container, path);

    }

    /// <summary>
    /// Load elements from xml file pointed to by path.
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public List<FolderElement> LoadElements(string path)
    {
        List<FolderElement> result = new List<FolderElement>();

        var attributes = Deserialize<List<FolderAttributes>>(path);
        if (attributes != null)
        {
            foreach (var attr in attributes)
            {
                var element = attr.ToElement();
                result.Add(element);
            }
        }

        return result;
    }

    /// <summary>
    /// Save XML serialization of object to named file.
    /// </summary>
    /// <param name="value"></param>
    /// <param name="fileName"></param>
    public static void SaveXml(Object value, string fileName)
    {
        // First serialize the object to memory stream,
        // in case of exception, the original file is not corrupted
        using (MemoryStream ms = new MemoryStream())
        {
            var stream = new System.IO.StreamWriter(ms);
            if (Serialize(value, stream))
            {
                // if the serialization succeeded, rewrite the file.
                File.WriteAllBytes(fileName, ms.ToArray());
            }
        }

    }

    /// <summary>
    /// Base-level method to serialize object to TextWriter.
    /// </summary>
    /// <param name="value"></param>
    /// <param name="output"></param>
    /// <returns></returns>
    public static bool Serialize<T>(object value, TextWriter output)
    {
        if (value == null) throw new ArgumentNullException("Serialize(value)");

        bool result = false;
        Type T = value.GetType();

        try
        {
            var xmlSerializer = new XmlSerializer(typeof(T));
            using (var xmlWriter = XmlWriter.Create(output, new XmlWriterSettings { Indent = true }))
            {
                xmlSerializer.Serialize(xmlWriter, value);
                result = true;
            }
        }
        catch (Exception)
        {
            // Log.Error(ex, "WriteXml {0}", T.Name);
        }

        return result;
    }

    public static T Deserialize<T>(string fileName)
    {
        T result = default(T);
        try
        {
            using (var stream = System.IO.File.OpenRead(fileName))
            {
                var serializer = new XmlSerializer(typeof(T));
                result = (T)serializer.Deserialize(stream);
            }
        }
        catch (Exception)
        {
            // Log.Error(ex, "Deserialize<{0}> from file {1}", typeof(T).Name, fileName);
        }
        return result;
    }

}
于 2016-07-23T03:08:56.627 回答