0

我正在尝试使用 ServiceStack.Text 反序列化包含嵌套类列表的对象。

序列化进行得很顺利,但是在尝试反序列化时,出现此错误:

System.TypeInitializationException:“ServiceStack.Text.Jsv.JsvReader 1' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Jsv.JsvReader1”的类型初始化程序引发了异常。---> System.TypeInitializationException:“ServiceStack.Text.Common.DeserializeList 2' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Jsv.JsvReader1”的类型初始化程序引发了异常。---> System.TypeInitializationException:“ServiceStack.Text.Jsv.JsvReader 1' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Common.DeserializeList2”的类型初始化程序引发了异常。---> System.TypeInitializationException: 'ServiceStack.Text.Jsv.JsvReader`1' 的类型初始化程序引发了异常。---> System.ArgumentException:为调用方法'Void set_Item(Int32,MyApp.MyClass)'提供的参数数量不正确

我的解决方案中没有名为 set_Item 的方法,在 ServiceStack.Text 程序集中(使用反射器)也找不到这样命名的方法。我不知道问题可能是什么......而且我需要一个快速的序列化类型,但我知道的最快的(protobuf-net)不支持嵌套列表。

有任何想法吗?导致问题的类如下(protomembers在那里,因为我测试了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;
        }
    }


}
4

2 回答 2

1

您不想从 IEnumerable 继承,因为它不太可能按照您期望的方式运行。即所有 Enumerables 都像 JSON Array/Collection 一样被序列化,并且其他属性被忽略。

仅具有 IEnumerable 接口的问题在于无法通用地填充它。因此,虽然您可以序列化它,但您将无法反序列化它。

如果你实现了一个集合接口,它也提供了填充它的能力,你会更成功,即IList<T>ICollection<T>

于 2011-10-16T00:24:45.117 回答
1

我有同样的问题。我需要我的类来继承 IDataErrorInfo,而问题出在indexed property上。不过,您可以在源代码中自行修复。在 OrmLiteConfigExtensions 中找到方法 GetModelDefinition 并查找:

GetValueFn = propertyInfo.GetPropertyGetterFn(), SetValueFn = propertyInfo.GetPropertySetterFn(),

仅将 GetValueFn 行替换为:

GetValueFn = (propertyInfo.GetIndexParameters().Length == 0)?null:propertyInfo.GetPropertyGetterFn(),

这样,它将跳过为引发异常的索引属性设置 GetValueFn 属性。

于 2013-08-21T01:29:20.310 回答