![](/img/trans.png)
[英]System.Tuple cannot be serialized because it does not have a parameterless constructor
[英]Tuple cannot be serialized because it does not have a parameterless constructor
我正在嘗試序列化下面提供的 QDatatables 類的實例,但出現錯誤:
System.Xml.dll 中出現類型為“System.InvalidOperationException”的異常,但未在用戶代碼中處理附加信息:存在反映類型“System.Collections.ObjectModel.ObservableCollection`1[DataRetrieval.Model.QDatatable]”的錯誤.
StackTrace:在 System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping 映射、StructModel 模型、布爾型 openModel、String typeName、RecursionLimiter 限制器)在 System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructML 模型,布爾型模型,字符串屬性打開, RecursionLimiter 限制器)在 System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel 模型,字符串 ns,ImportContext 上下文,字符串數據類型,XmlAttributes a,布爾重復,布爾 openModel,RecursionLimiter 限制器)
InnerException: {"System.Tuple`2[System.String,System.String] 無法序列化,因為它沒有無參數構造函數。"}
任何人都可以幫助找到丟失的東西嗎?
我的序列化功能:
public string serialize()
{
StringWriter sw = new StringWriter();
XmlSerializer s = new XmlSerializer(this.GetType());
s.Serialize(sw, this);
return sw.ToString();
}
QDatatables 類:
[Serializable()]
public class QDatatables : BindableBase
{
private ObservableCollection<QDatatable> _list;
public ObservableCollection<QDatatable> List
{
get { return _list ?? (_list=new ObservableCollection<QDatatable>()); }
set { SetProperty(ref _list, value); }
}
public string serialize()
{
StringWriter sw = new StringWriter();
XmlSerializer s = new XmlSerializer(typeof(ObservableCollection<QDatatable>));
s.Serialize(sw, List);
return sw.ToString();
}
}
QDatatable 類
[Serializable()]
public class QDatatable : BindableBase
{
private int _id;
public int ID
{
get { return _id; }
set { SetProperty(ref _id, value); }
}
private String _name;
public String Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private WhereParams _params;
public WhereParams Params
{
get { return _params; }
set { SetProperty(ref _params, value); }
}
private bool _isexpanded;
public bool IsExpanded
{
get { return _isexpanded; }
set { SetProperty(ref _isexpanded, value); }
}
}
WhereParam 類:
public class WhereParams : BindableBase
{
private Dictionary<int, WhereParam> _dictionaryIdToWhereParam;
private ObservableCollection<WhereParam> _list;
public ObservableCollection<WhereParam> List
{
get { return _list ?? (_list = new ObservableCollection<WhereParam>()); }
set { SetProperty(ref _list, value); }
}
public WhereParam GetById(int id)
{
return List.First(w => w.ID == id);
}
public string serialize()
{
StringWriter sw = new StringWriter();
XmlSerializer s = new XmlSerializer(this.GetType());
s.Serialize(sw, this);
return sw.ToString();
}
}
[Serializable()]
public class WhereParam:BindableBase
{
private int _id;
public int ID
{
get { return _id; }
set { SetProperty(ref _id, value); }
}
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private ParamType _type;
public ParamType Type
{
get { return _type; }
set { SetProperty(ref _type, value); }
}
}
參數類型類:
[XmlInclude(typeof(DateTimeType))]
[XmlInclude(typeof(StringType))]
[XmlInclude(typeof(IntType))]
[XmlInclude(typeof(FloatgType))]
[XmlInclude(typeof(BoolType))]
[XmlInclude(typeof(NullableBoolType))]
[XmlInclude(typeof(ListMulti))]
[XmlInclude(typeof(ListSingle))]
[XmlInclude(typeof(StringMulti))]
public class ParamType: BindableBase
{
private int _typeID;
public int TypeID
{
get { return _typeID; }
set { SetProperty(ref _typeID, value); }
}
private ParamTypeEnum _typeName;
public ParamTypeEnum TypeName
{
get { return _typeName; }
set { SetProperty(ref _typeName, value); }
}
}
public class DateTimeType : ParamType
{
private DateTime? _datefrom;
public DateTime? Datefrom
{
get { return _datefrom; }
set { SetProperty(ref _datefrom, value); }
}
private DateTime? _dateTo;
public DateTime? DateTo
{
get { return _dateTo; }
set {
SetProperty(ref _dateTo, value); }
}
}
public class StringType : ParamType
{
private string _stringContent;
public string StringContent
{
get { return _stringContent; }
set {
SetProperty(ref _stringContent, value); }
}
}
public class IntType : ParamType
{
private int _intContent;
public int IntContent
{
get { return _intContent; }
set { SetProperty(ref _intContent, value); }
}
}
public class FloatgType : ParamType
{
private float _floatContent;
public float FloatContent
{
get { return _floatContent; }
set { SetProperty(ref _floatContent, value); }
}
}
public class BoolType : ParamType
{
private bool _boolTypeValue;
public bool BoolTypeValue
{
get { return _boolTypeValue; }
set { SetProperty(ref _boolTypeValue, value); }
}
}
public class NullableBoolType : ParamType
{
private bool? _nullableBoolTypeValue;
public bool? NullableBoolTypeValue
{
get { return _nullableBoolTypeValue; }
set { SetProperty(ref _nullableBoolTypeValue, value); }
}
}
public class ListMulti : ParamType
{
private ObservableCollection<Tuple<string, string>> _listMultiItems;
public ObservableCollection<Tuple<string, string>> ListMultiItems
{
get { return _listMultiItems; }
set { SetProperty(ref _listMultiItems, value); }
}
private ObservableCollection<Tuple<string, string>> _selectedListMulti;
public ObservableCollection<Tuple<string, string>> SelectedItemsListMulti
{
get { return _selectedListMulti ?? (_selectedListMulti = new ObservableCollection<Tuple<string,string>>()); }
set {
SetProperty(ref _selectedListMulti, value); }
}
}
public class ListSingle : ParamType
{
private ObservableCollection<Tuple<string, string>> _listSingleItems;
public ObservableCollection<Tuple<string, string>> ListSingleItems
{
get { return _listSingleItems; }
set { SetProperty(ref _listSingleItems, value); }
}
//private ObservableCollection<Tuple<string, string>> _listSingleItems;
//public ObservableCollection<Tuple<string, string>> ListSingleItems
//{
// get { return _listSingleItems; }
// set { SetProperty(ref _listSingleItems, value); }
//}
}
public class StringMulti : ParamType
{
private string _listMultiCollection;
public string ListMultiCollection
{
get { return _listMultiCollection; }
set { SetProperty(ref _listMultiCollection, value); }
}
}
public enum ParamTypeEnum
{
boolType,
nullableboolType,
intType,
floatType,
stringType,
datetimeType,
listmultiType,
stringlistmultiType,
};
問題是您的類ListMulti
等使用的類Tuple<T1, T2>
沒有默認構造函數,因為元組只能通過Tuple.Create()
公開創建。 但是, XmlSerializer
要求類具有無參數的默認構造函數,如果遇到沒有默認構造函數的類型,則會拋出異常。 這是您看到的例外。
一種解決方法是將代理屬性添加到您的類,重新打包並以可序列化的形式返回其數據。 然后,使用XmlIgnore
標記“真實”屬性。 對於ListMulti
持有的字符串元組集合, string [][]
代理屬性是有意義的:
public class ListMulti : ParamType
{
[XmlArray("ListMultiItems")]
[XmlArrayItem("Pair")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public string[][] SerializableListMultiItems
{
get
{
return ListMultiItems.ToPairArray();
}
set
{
ListMultiItems.SetFromPairArray(value);
}
}
[XmlArray("SelectedItemsListMulti")]
[XmlArrayItem("Pair")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public string[][] SerializableSelectedItemsListMulti
{
get
{
return SelectedItemsListMulti.ToPairArray();
}
set
{
SelectedItemsListMulti.SetFromPairArray(value);
}
}
private ObservableCollection<Tuple<string, string>> _listMultiItems = new ObservableCollection<Tuple<string, string>>();
[XmlIgnore]
public ObservableCollection<Tuple<string, string>> ListMultiItems
{
get { return _listMultiItems; }
set { SetProperty(ref _listMultiItems, value); }
}
private ObservableCollection<Tuple<string, string>> _selectedListMulti;
[XmlIgnore]
public ObservableCollection<Tuple<string, string>> SelectedItemsListMulti
{
get { return _selectedListMulti ?? (_selectedListMulti = new ObservableCollection<Tuple<string, string>>()); }
set
{
SetProperty(ref _selectedListMulti, value);
}
}
}
使用擴展方法:
public static class TupleExtensions
{
public static T[][] ToPairArray<T>(this IEnumerable<Tuple<T, T>> collection)
{
return collection == null ? null : collection.Select(t => new[] { t.Item1, t.Item2 }).ToArray();
}
public static void SetFromPairArray<T>(this ICollection<Tuple<T, T>> collection, T[][] array)
{
if (collection == null)
throw new ArgumentNullException();
collection.Clear();
foreach (var pair in array)
{
if (pair.Length != 2)
throw new ArgumentException("Inner array did not have length 2");
collection.Add(Tuple.Create(pair[0], pair[1]));
}
}
}
您需要對ListSingle
進行類似的修復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.