我正在尝试使用ServiceStack.Text对包含嵌套类的列表的对象进行反序列化。
序列化进展顺利,但在尝试反序列化时,我收到此错误:
System.TypeInitializationException:类型初始值设定项 'ServiceStack.Text.Jsv.JsvReader
1' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Jsv.JsvReader
1'引发了异常。 ---> System.TypeInitializationException:类型初始值设定项 'ServiceStack.Text.Common.DeserializeList2' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Jsv.JsvReader
1'抛出异常。 ---> System.TypeInitializationException:类型初始值设定项 'ServiceStack.Text.Jsv.JsvReader1' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Common.DeserializeList
2'引发了异常。 ---> System.TypeInitializationException:类型初始值设定项 'ServiceStack.Text.Jsv.JsvReader`1'引发了异常。 ---> System.ArgumentException:提供的参数数量不正确 调用方法'Void set_Item(Int32,MyApp.MyClass)'
我的解决方案中没有名为set_Item的方法,也无法在ServiceStack.Text程序集中找到这样的方法(使用反射器)。我不知道问题可能是什么......我需要一个快速序列化类型,但我知道的最快(protobuf-net)不支持嵌套列表。
有什么想法吗?造成这个问题的类是下面的(因为我测试了protobuf方法,所以原始组件就在那里)
[Serializable]
/// <summary>
/// Description of Livres.
/// </summary>
public class Livres : IEnumerable<Livre>
{
[ProtoMember(1)]
private List<Livre> listeLivres;
public List<Livre> ListeLivres
{
get { return listeLivres; }
set { listeLivres = value; }
}
public List<string> NomLivres
{
get
{
List<string> lst = new List<string>();
foreach (Livre livre in this.listeLivres)
{
lst.Add(livre.NomLivre);
}
return lst;
}
}
public int Count
{
get
{
return ((this.listeLivres != null) ? this.listeLivres.Count : 0);
}
}
public Livre this[string nomLivre]
{
get
{
nomLivre = nomLivre.ToLower();
if (nomLivre == "")
{
return null;
}
try
{
var u = this.listeLivres.Single(book => book.NomLivre.ToLower() == nomLivre);
return u;
}
catch (InvalidOperationException)
{
string pattern = "^[0-9][a-zA-Z]+$";
Regex reg = new Regex(pattern);
if (reg.IsMatch(nomLivre))
{
string nom = nomLivre[0].ToString() + " ";
nom += nomLivre.Substring(1).ToLower();
try
{
var u = this.listeLivres.Single(book => book.NomLivre.ToLower() == nom);
return u;
}
catch (Exception)
{
return null;
}
}
else
return null;
}
}
set
{
if (nomLivre == "")
{
throw new
ArgumentNullException("L'index ne doit pas être une chaine vide.");
}
try
{
Livre liv = this.listeLivres.Single(book => book.NomLivre == nomLivre);
liv = value;
}
catch (InvalidOperationException ex)
{
string pattern = "^[0-9][a-zA-Z]+$";
Regex reg = new Regex(pattern);
if (reg.IsMatch(nomLivre))
{
string nom = nomLivre[0].ToString() + " ";
nom += nomLivre.Substring(1);
try
{
Livre L = this.listeLivres.Single(book => book.NomLivre == nom);
L = value;
}
catch (Exception e)
{
throw new ArgumentException("Ce nom de livre n'existe pas dans la liste", e);
}
}
else
throw new ArgumentException("Ce nom de livre n'existe pas dans la liste", ex);
}
}
}
/// <summary>
/// Obtient ou définit le Livre à l'index spécifié - 1
/// Exceptions:
/// ArgumentOutOfRangeException
/// </summary>
public Livre this[int index]
{
get
{
if (index < 1 || index > this.listeLivres.Count)
{
throw new
ArgumentOutOfRangeException("L'index spécifié n'était pas correct");
}
return this.listeLivres[index-1];
}
set
{
if (index < 1 || index > this.listeLivres.Count)
{
throw new
ArgumentOutOfRangeException("L'index spécifié n'était pas correct");
}
this.listeLivres[index - 1] = value;
}
}
#region Constructeurs
public Livres()
{
this.listeLivres = new List<Livre>();
}
public Livres(Livre livre)
: this()
{
this.listeLivres.Add(livre);
}
#endregion
/// <summary>
/// Retourne le verset correspondant si il existe, sinon null
/// Exceptions
/// ArgumentException
/// </summary>
/// <param name="referenceComplete">La référence du verset sous forme de chaine (ex: "1 Jean 5:19")</param>
public Verset GetVerset(string referenceComplete)
{
if (string.IsNullOrWhiteSpace(referenceComplete))
return null;
string[] tab = referenceComplete.Split();
try
{
string livre = "";
int chapitre;
int verset;
if (tab.Length>2)
{
livre = tab[0];
}
livre += tab[tab.Length -2];
string [] tabVerse = tab[tab.Length -1].Split(':');
chapitre = Convert.ToInt32(tabVerse[0]);
verset = Convert.ToInt32(tabVerse[1]);
return this[livre][chapitre][verset];
}
catch (Exception ex)
{
throw new ArgumentException("Il n'y a aucun verset avec cette référence",ex);
}
}
public void Add(Livre livre)
{
this.listeLivres.Add(livre);
}
public static Livres operator +(Livres livres, Livre livre)
{
livres.Add(livre);
return livres;
}
public IEnumerator<Livre> GetEnumerator()
{
foreach (Livre item in this.listeLivres)
{
yield return item;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public void Serialize(string pathName= "BibleData.txt")
{
try
{
#region ServiceStack Serializer
TextWriter tw = new StreamWriter(pathName);
TypeSerializer<Livres> TypeSrlzr = new TypeSerializer<Livres>();
TypeSrlzr.SerializeToWriter(this,tw);
//TypeSerializer.SerializeToWriter(this,tw);
tw.Close();
#endregion
}
catch (Exception)
{
throw;
}
}
public static Livres Deserialize(string pathName= "BibleData.txt")
{
try
{
Livres Bible;
#region ServiceStack Deserializer
TextReader tr = new StreamReader(pathName);
TypeSerializer<Livres> typeSrlzr = new TypeSerializer<Livres>();
Bible = typeSrlzr.DeserializeFromReader(tr);
//Bible = TypeSerializer<Livres>.DeserializeFromReader(tr);
#endregion
return Bible;
}
catch (Exception) {
throw;
}
}
}
答案 0 :(得分:1)
您不希望从IEnumerable继承,因为它不会以您期望的方式运行。即所有Enumerables都像JSON数组/集合一样被序列化,并忽略其他属性。
只有IEnumerable接口的问题是没有办法一般填充它。因此,虽然您可以序列化它,但您将无法对其进行反序列化。
如果您实现了一个也能够填充它的集合界面,即 IList&lt; T&gt; 或 ICollection&lt; T&gt; ,那么您会更成功。
答案 1 :(得分:1)
我遇到了同样的问题。我需要我的类继承IDataErrorInfo,问题出在索引属性。您可以在源代码中自行修复它。在OrmLiteConfigExtensions中找到方法GetModelDefinition并查找:
GetValueFn = propertyInfo.GetPropertyGetterFn(), SetValueFn = propertyInfo.GetPropertySetterFn(),
仅使用:
替换GetValueFn行GetValueFn =(propertyInfo.GetIndexParameters()。Length == 0)?null:propertyInfo.GetPropertyGetterFn(),
这样它就会跳过为抛出异常的索引属性设置GetValueFn属性。