Исключение сериализации ServiceStack.Text (неверное количество аргументов, предоставленных для вызова метода 'Void set_Item (Int32, MyApp.MyClass)') - PullRequest
0 голосов
/ 09 октября 2011

Я пытаюсь десериализовать объект, содержащий вложенные списки классов, с помощью 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 ]

1 голос
/ 21 августа 2013

У меня была такая же проблема. Мне нужно, чтобы мои классы наследовали IDataErrorInfo, и проблема в индексированном свойстве . Вы можете исправить это самостоятельно в исходном коде. В OrmLiteConfigExtensions найдите метод GetModelDefinition и найдите:

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

заменить строку GetValueFn только на:

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

Таким образом, пропускается установка свойства GetValueFn для индексированных свойств, которое выдает исключение.

1 голос
/ 16 октября 2011

Вы не хотите наследовать от IEnumerable, поскольку он вряд ли будет вести себя так, как вы ожидаете. все перечислимые объекты сериализуются как массив / коллекция JSON, а дополнительные свойства игнорируются.

Проблема с наличием только интерфейса IEnumerable заключается в том, что его невозможно заполнить вообще. Таким образом, хотя вы сможете сериализовать его, вы не сможете десериализовать его.

Вы были бы более успешными, если бы вы реализовали интерфейс коллекции, который также предоставляет возможность его заполнения, т.е. IList или ICollection .

...