Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Почему вылетает exception при десериализации?

#c_sharp #net #wpf


Есть класс :

    [Serializable]
    public class UserAccount
    {
        public string Name { get; set; }
        public string Surname { get; set; }
        public string Login { get; set; }
        public PasswordBox Password { get; set; }

        public UserAccount(string _name, string _surname, string _login, PasswordBox
_password)
        {
            Name = _name;
            Surname = _surname;
            Login = _login;
            Password = _password;
        } 
    }


Метод десериализации:

        public void Deserialize()
        {
            try
            {
                FileStream fs = new FileStream("..\\..\\Accounts.dat", FileMode.Open);
                BinaryFormatter formatter = new BinaryFormatter();
                listUsers = (List)formatter.Deserialize(fs);//вылетает
exception
                fs.Close();
            }

            catch
            {
                listUsers = new List();
            }
        }


Ошибка: 


  Exception thrown: 'System.Windows.Markup.XamlParseException' in
  PresentationFramework.dll
       Additional information: 'The invocation of the constructor on type 'Gallery.ViewModels.LoginViewModel'
that matches the specified
  binding constraints threw an exception.' Line number '15' and line
  position '10'.


Update

public class LoginViewModel : INotifyPropertyChanged
    {
        private List listUsers;

        public LoginViewModel()
        {
            _currentName = String.Empty;
            _currentSurname = String.Empty;
            _currentLogin = String.Empty;
            _currentPasswordBox = new PasswordBox();
            Deserialize();
        }
        private string _currentSurname;

        public string CurrentSurname
        {
            get
            {
                return _currentSurname;
            }
            set
            {
                _currentSurname = value;
                OnPropertyChanged();
            }
        }

        private string _currentName;

        public string CurrentName
        {
            get
            {
                return _currentName;
            }
            set
            {
                _currentName = value;
                OnPropertyChanged();
            }
        }

        private string _currentLogin;

        public string CurrentLogin
        {
            get
            {
                return _currentLogin;
            }
            set
            {
                _currentLogin = value;
                OnPropertyChanged();
            }
        }

        private PasswordBox _currentPasswordBox;

        public PasswordBox currentPassword
        {
            get { return _currentPasswordBox; }
            set
            {
                _currentPasswordBox = value;
                OnPropertyChanged();
            }
        }
        private RegistrationCheckCommand checkReg;
        public ICommand ButtonClick
        {
            get { return checkReg ?? (checkReg = new RegistrationCheckCommand(o =>
AddNewAccount())); }
        }

        private void AddNewAccount()
        {
            UserAccount user = new UserAccount(CurrentName, CurrentSurname, CurrentLogin,
currentPassword);
            listUsers.Add(user);
            Serialize();
            MessageBox.Show("Account adding!");
        }

        public void Serialize()
        {

            try
            {
                FileStream fs = new FileStream("..\\..\\Accounts.dat", FileMode.Create);
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(fs, listUsers);
                fs.Close();
            }
            catch
            {

            }
        }

        public void Deserialize()
        {
            //try
            //{
                FileStream fs = new FileStream("..\\..\\Accounts.dat", FileMode.Open);
                BinaryFormatter formatter = new BinaryFormatter();
                listUsers = (List)formatter.Deserialize(fs);
                fs.Close();
            //}

            //catch
            //{
            //    listUsers = new List();
            //}
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName
= null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }


    }


Xaml





    



    
        
            
            
            
            
            
        
    
    
        
            
            
            
            
            
            
            
            
            
        
    





StackTrace


  at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
  
  at
  System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler
  handler, __BinaryParser serParser, Boolean fCheck, Boolean
  isCrossAppDomain, IMethodCallMessage methodCallMessage)
  
  at
  System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
  serializationStream, HeaderHandler handler, Boolean fCheck, Boolean
  isCrossAppDomain, IMethodCallMessage methodCallMessage)
  
  at
  System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
  serializationStream)
  
  at Gallery.ViewModels.LoginViewModel.Deserialize() in
  C:\Users\Константин\Documents\Visual Studio
  2015\Projects\Gallery\Gallery\ViewModels\LoginViewModel.cs:line
  121

    


Ответы

Ответ 1



Замените тип данного свойства public PasswordBox Password { get; set; } на string или любой другой тип, не являющийся коллекцией и помеченный как сериализуемый. PasswordBox - контрол, контролы не сериализуются с помощью стандартных сериализоторов, т.к. являются рекурсивной коллекцией, т.е. любой контрол содержит коллекцию дочерних котролов, пустую или нет - неважно. После изменений, удалите файл данных, повторите сериализацию и десериализацию. С ограничениями может быть использован специальный сериализатор либо ручная сериализация.

Ответ 2



Судя по всему у вас ошибка возникает из-за Accounts.dat Попробуйте создать новый .dat следующим методом public void Serialize() { FileStream fs = new FileStream("..\\..\\Accounts.dat", FileMode.Create); try { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fs, listUsers); } finally { fs.Close(); } } Проверка сериализации в файл и десериализации из файла также работает без ошибок. [Serializable] public class PasswordBox { } [Serializable] public class UserAccount { public string Name { get; set; } public string Surname { get; set; } public string Login { get; set; } public PasswordBox Password { get; set; } public UserAccount(string _name, string _surname, string _login, PasswordBox _password) { Name = _name; Surname = _surname; Login = _login; Password = _password; } } void Main() { List listUsers = new List(); listUsers.Add(new UserAccount("n", "s", "l", new PasswordBox())); BinaryFormatter formatter = new BinaryFormatter(); FileStream fs1 = new FileStream("..\\..\\Accounts.dat", FileMode.Create); try { formatter.Serialize(fs1, listUsers); } finally { fs1.Close(); } FileStream fs2 = new FileStream("..\\..\\Accounts.dat", FileMode.Open); try { listUsers = (List) formatter.Deserialize(fs2); } finally { fs2.Close(); } listUsers.Dump(); }

Комментариев нет:

Отправить комментарий