XML序列化错误 - 反映类型时出错 [英] XML Serialization Error - There was an error reflecting type
问题描述
我想从配置文件中序列化几个自定义设置。
以下是我的设置:
< FavouriteTools>
< favouriteTool PluginPlaceHolder =FavoriteTool1PlugInName =Brightness
PlugInType =2DPlugInAssemblyName =Micro.DigiMic.Plugins.AreaBasedOnBrightness.AreaBasedOnBrightnessPlugin
GUID =0000c03a-b891- 4ebd-87d7-5fbc19073a1a/>
< favouriteTool PluginPlaceHolder =FavoriteTool2PlugInName =CircleArea
PlugInType =2DPlugInAssemblyName =Micro.DigiMic.Plugins.CircleAreaPlugin.CircleAreaPlugin
GUID =0000c06a-b891- 4ebd-87d7-5fbc19073a1a/>
< favouriteTool PluginPlaceHolder =FavoriteTool3PlugInName =Contour Area
PlugInType =2DPlugInAssemblyName =Micro.DigiMic.Plugins.ContourAreaPlugin.ContourAreaPlugin
GUID =0000c11a-b891 -4ebd-87d7-5fbc19073a1a/>
他们。这是我的课程。
// FavouriteTools - 根节点
[Serializable]
[ FavoriteTools)]
[ConfigurationCollection(typeof(FavouriteTool),AddItemName =favouriteTool,CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class FavouriteToolsCollection
:ConfigurationElementCollection
{
//这里几个plublic方法
}
// favouriteTool - 子节点
[Serializable]
[XmlType(favouriteTool)]
public FavouriteTool类:ConfigurationElement
{
///< summary>
///获取或设置Plugin PlaceHolder的值。
///< / summary>
///< value>文本颜色。< / value>
[ConfigurationProperty(PluginPlaceHolder,IsRequired = false)]
public string PlugPlaceHolder
{
get {return(string)base [PluginPlaceHolder]; }
set {base [PluginPlaceHolder] = value; }
}
//几乎没有像上面这样的属性
}
$ b我试图序列化下面的类,但在下面得到异常如
XmlSerializer xmlinf = new XmlSerializer(data.GetType());
`data`是`ExportUser`
[Serializable]
public class ExportUser
{
public bool IsMetric {get;组; }
[XmlArray(FavoriteTools)]
[XmlArrayItem(favouriteTool)]
public FavouriteToolsCollection FavoriteTools {get;组; }
}
$ b $
我收到此错误 -反映类型为ExportUser
,并在内部异常中错误说 -反映类型为FavoriteTools的错误
。
有没有遗漏吗?
更新:
在看到内部异常后,错误是
{您必须在System.Configuration.ConfigurationLockCollection上实现一个默认访问器, ICollection。}
反映Zeiss.Micro.DigiMic.Application.FavouriteTool类型时出现错误。
但是我在
FavouriteToolsCollection
中有一个默认访问器:public FavouriteTool this [int index]
{
get
{
return(FavouriteTool) BaseGet(index);
}
set
{
if(this.BaseGet(index)!= null)
{
this.BaseRemoveAt ;
}
this.BaseAdd(index,value);
}
}
还有什么缺失?
解决方案OK。我刚刚遇到这个。并使用包装器对象解决它。
我做的是为我想要的
serialize创建一个简单的包装器对象。我的case是一个ConfigurationCollection。我序列化,并创建一个几个适配器从可序列化对象映射到实际对象,反之亦然。使用system.Xml 。串行化;
//这是FolderElement的XML包装器。
public class FolderAttributes
{
[XmlAttribute(Name)]
public string Name {get;组; }
[XmlAttribute(Volume)]
public string Volume {get;组; }
[XmlAttribute(Path)]
public string Path {get;组; }
[XmlAttribute(Selected)]
public bool Selected {get;组; }
[XmlAttribute(Active)]
public bool Active {get;组; }
///< summary>
///工厂方法。
///从FolderElment创建FolderAttributes的新实例。
///< / summary>
///< param name =element>< / param>
///< return>< / 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>
///将此实例转换为FolderElement。
///< / summary>
///< return>< / 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 [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>
///元素的返回键值。
///< / summary>
///< param name =element>< / param>
///< return>< / returns>
///< remarks>< / remarks>
protected override对象GetElementKey(ConfigurationElement元素)
{
return((FolderElement)element).Name;
}
///< summary>
///默认索引属性。
///< / summary>
///< param name =index>< / param>
///< return>< / returns>
public FolderElement this [int index]
{
get {return(FolderElement)BaseGet(index); }
}
///< summary>
///按名称返回内容元素。
///< / summary>
///< param name =name>< / param>
///< return>< / returns>
public FolderElement GetElementByName(string name)
{
return(FolderElement)BaseGet(name);
}
public IEnumerable< FolderElement>元素
{
get
{
for(int index = 0; index< this.Count; index ++)yield return(FolderElement)BaseGet(index);
}
}
///< summary>
///添加一个元素到集合
///< / summary>
///< param name =element>< / param>
public void AddElement(FolderElement element)
{
BaseAdd(element);
}
}
public class FolderSection:ConfigurationSection
{
//属性参数必须常数表达式。
protected const string _elementsTag =elements;
[ConfigurationProperty(_elementsTag,Options = ConfigurationPropertyOptions.IsDefaultCollection)]
public FolderCollection元素
{
get {return((FolderCollection)(base [_elementsTag])) ; }
set {base [_elementsTag] = value; }
}
public void SaveElements(ConfigurationElementCollection elements,string path)
{
var container = new List< FolderAttributes>();
foreach(元素中的FolderElement元素)
{
container.Add(FolderAttributes.FromElement(element));
}
// XmlHelper.SaveXml(container,path);
SaveXml(container,path);
}
///< summary>
///从路径指向的xml文件加载元素。
///< / summary>
///< param name =path>< / param>
///< return>< / 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)
{
var element = attr.ToElement
result.Add(element);
}
}
返回结果;
}
///< summary>
///将对象的XML序列化保存到命名文件。
///< / summary>
///< param name =value>< / param>
///< param name =fileName>< / param>
public static void SaveXml(Object value,string fileName)
{
//首先将对象序列化到内存流,
//在异常情况下,原始文件不是损坏
使用(MemoryStream ms = new MemoryStream())
{
var stream = new System.IO.StreamWriter(ms);
if(Serialize(value,stream))
{
//如果序列化成功,重写文件。
File.WriteAllBytes(fileName,ms.ToArray());
}
}
}
///< summary>
///将对象序列化为TextWriter的基本方法。
///< / summary>
///< param name =value>< / param>
///< param name =output>< / param>
///< return>< / 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);
}
返回结果;
}
public static T Deserialize< T>(string fileName)
{
T result = default(T);
try
{
using(var stream = System.IO.File.OpenRead(fileName))
{
var serializer = new XmlSerializer ;
result =(T)serializer.Deserialize(stream);
}
}
catch(Exception)
{
// Log.Error(ex,Deserialize< {0}> from file {1} typeof(T).Name,fileName);
}
return result;
}
}
I am trying to serialize few custom settings from configuration file. Below are my settings:
<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" />
But I get error during serializing them. Here are my classes.
//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; } }
I get this error -
There was an error reflecting type 'ExportUser'
and in inner exception the error says -There was an error reflecting type 'FavoriteTools'
.Is there anything missing?
Update:
After seeing the inner exception, the error is
{"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'.
But I do have a default accessor in
FavouriteToolsCollection
class:public FavouriteTool this[int index] { get { return (FavouriteTool)BaseGet(index); } set { if (this.BaseGet(index) != null) { this.BaseRemoveAt(index); } this.BaseAdd(index, value); } }
What more is missing?
解决方案OK. I just encountered this. And solved it using a wrapper object.
What I did was to create a simple wrapper object for the thing I want to serialize. I my case it is a ConfigurationCollection. I serialize that and create a couple adapters to map from the serializable object to the actual object and vice versa.
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; } }
这篇关于XML序列化错误 - 反映类型时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!