C#中的SerializationException

时间:2015-12-04 13:42:44

标签: c# generics serialization soapformatter

我在CSharp的代码中有以下异常:

  

序列化程序不会计算泛型类型的序列化:   System.Collections.Generic.SortedSet`

这是我的代码有问题(在FileStreamer类中):

import string
try:
    name = raw_input("What is your name? ")
    assert  any([char not in string.ascii_letters for char in name]) is False
except AssertionError:
    print("Your name must consist of letters only")
else:
    print("Thank you for entering your name.")

以下是我在项目中使用的以下课程:

主要班级:

 public static bool SoapSave(SortedSet<T> set, string filename)
        {
            FileStream stream = File.Create(filename);
            SoapFormatter formatter = new SoapFormatter();

            formatter.Serialize(stream, set);
            stream.Close();
            return true;
        }

Authentification.cs

 class Program
    {
        public static void Main(string[] args)
        {
            GestAuthentification ga = new Authentification () ;

             try 
             {
                 ga.addUser("bob","123");
                 ga.removeUser("bob");
                 ga.removeUser("bob");
             } catch (UserUnknown e) {
                 Console.WriteLine(e.Login +" est inconnu du système! on ne peut le retirer.");
             } catch (UserExists e) {
                Console.WriteLine(e.Login +" est déjà dans le système! on ne peut le recréer.");
             }

             try 
             {
                ga.addUser("bob","123");
                ga.authentify("bob","123");
                ga.authentify("bob","456");
             } catch (WrongPassword e) {
                Console.WriteLine(e.Login+" s'est trompé de password !");
             } catch (UserExists e) {
                Console.WriteLine(e.Login +" est déjà dans le système! on ne peut le recréer.");
             } catch (UserUnknown e) {
                Console.WriteLine(e.Login +" est inconnu du système! on ne peut le retirer.");
             }

        //Until here it works
             try 
             {
                ga.save("users.txt");
                GestAuthentification gb = new Authentification();
                gb.load("users.txt");
                gb.authentify("bob","123");
                Console.WriteLine("Test sauvegarde/chargement réussi !");
             } catch (UserUnknown e) {
                Console.WriteLine(e.Login +" est n'est plus connu. Problème de sauvegarde/chargement.");
             } catch (WrongPassword e) {
                Console.WriteLine(e.Login+" s'est trompé de password !Problème de sauvegarde/chargement."); 
             } catch (IOException e) {
                Console.WriteLine(e);
            }
        }
        }

FileStreamer.cs

[Serializable]
    public class Authentification: GestAuthentification
    {
        private SortedSet<User> userset;

        public Authentification()
        {
            this.userset = new SortedSet<User>();
        }

        public void addUser(String login, String pass)
        {
            if (userset.Count() == 0)
            {
                User usr0 = new User(login, pass);
                userset.Add(usr0);
                Console.WriteLine(usr0._login + " a été ajoute");

                return;
            }
            else
            {

                foreach (User u in userset)
                {
                    if (u._login.Equals(login))
                    {
                        throw new UserExists(u);
                    }
                }
                User usr = new User(login, pass);
                userset.Add(usr);
                Console.WriteLine(usr._login + " a été ajoute");
            }
        }

        public void removeUser(String login)
        {
            foreach (User u in userset)
            {
                if (u._login.Equals(login))
                {
                    userset.Remove(u);
                    Console.WriteLine(u._login + " a été retiré.");
                    return;
                }
            }
            User usr = new User(login,"");
            throw new UserUnknown(usr);
        }

        public void authentify(String login, String Pass)
        {
            foreach (User u in userset)
            {
                if (u._login.Equals(login)&&u._password.Equals(Pass))
                {
                    Console.WriteLine(u._login + " a été authenthifié.");
                    return;
                }
                else if((u._login.Equals(login))&&(u._password.Equals(Pass)==false))
                {
                    throw new WrongPassword(u);
                }
            }
            User usr = new User(login, "");
            throw new UserUnknown(usr);
        }

        public void load(String path)
        {
            FileStreamer<User>.SoapLoad(path);
        }

        public void save(String path)
        {
            FileStreamer<User>.SoapSave(userset, path);
        }
    }

User.cs

public class FileStreamer<T>
    {
        public static bool SoapSave(SortedSet<T> set, string filename)
        {
            FileStream stream = File.Create(filename);
            SoapFormatter formatter = new SoapFormatter();

            formatter.Serialize(stream, set);
            stream.Close();
            return true;
        }

        public static SortedSet<T> SoapLoad(string filename)
        {
            FileStream stream = File.OpenRead(filename);
            SoapFormatter formatter = new SoapFormatter();

            SortedSet<T> set = (SortedSet<T>)formatter.Deserialize(stream);
            stream.Close();
            return set;
        }
    }

那么我的项目中序列化的问题在哪里,以及如何纠正它?

感谢。

1 个答案:

答案 0 :(得分:1)

在现代.Net环境中使用SoapFormatter可能会遇到任何问题。来自docs

  

从.NET Framework 2.0开始,此类已过时。请改用BinaryFormatter。

话虽如此,正如您所注意到的,SoapFormatter不支持泛型。但它确实支持数组,这些数组早在.Net 1就已存在。因此,您可以将SortedSet<T>序列化为数组:

public class FileStreamer<T>
{
    static void SoapSave(SortedSet<T> set, Stream stream)
    {
        var formatter = new SoapFormatter();
        formatter.Serialize(stream, set.ToArray());
    }

    public static SortedSet<T> SoapLoad(Stream stream)
    {
        var formatter = new SoapFormatter();
        var array = (T [])formatter.Deserialize(stream);
        return new SortedSet<T>(array);
    }

    public static bool SoapSave(SortedSet<T> set, string filename)
    {
        using (var stream = File.Create(filename))
        {
            SoapSave(set, stream);
        }
        return true;
    }

    public static SortedSet<T> SoapLoad(string filename)
    {
        using (var stream = File.OpenRead(filename))
        {
            return SoapLoad(stream);
        }
    }
}

注意SoapFormatter还要求您将User课程标记为[Serializable]

[Serializable]
public class User : IComparable<User>
{
    // Remainder of the class unchanged.
}