ServiceStack.Text序列化异常(为调用方法'Void set_Item(Int32,MyApp.MyClass)'提供的参数数量不正确)

时间:2011-10-08 23:10:45

标签: c# exception serialization deserialization servicestack

我正在尝试使用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.DeserializeList 2' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Jsv.JsvReader 1'抛出异常。 --->   System.TypeInitializationException:类型初始值设定项   'ServiceStack.Text.Jsv.JsvReader 1' 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;
        }
    }


}

2 个答案:

答案 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属性。