【问题标题】:Loading XML document loads the same group twice加载 XML 文档两次加载相同的组
【发布时间】:2017-02-22 11:25:37
【问题描述】:

一些课程要开始,我正在写它们,以便您可以重现我的问题:

public class PermissionObject
{
    public string permissionName;
    public string permissionObject;
    public bool permissionGranted;

    public PermissionObject()
    {
        permissionName = "";
        permissionObject = "";
        permissionGranted = true;
    }

    public PermissionObject(string name, string obj, bool granted)
    {
        permissionName = name;
        permissionObject = obj;
        permissionGranted = granted;
    }
}

public class Config
{
    public string cmsDataPath = "";
    public string cmsIP = "";
    public List<UserClass> usersCMS = new List<UserClass>();
    static public string pathToConfig = @"E:\testconpcms.xml";
    public string cardServerAddress = "";

    public void Save()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Config));
        using (Stream fileStream = new FileStream(pathToConfig, FileMode.Create))
        {
            serializer.Serialize(fileStream, this);
        }
    }

    public static Config Load()
    {
        if (File.Exists(pathToConfig))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Config));
            try
            {
                using (Stream fileStream = new FileStream(pathToConfig, FileMode.Open))
                {
                    return (Config)serializer.Deserialize(fileStream);
                }
            }
            catch (Exception ex)
            {
                return new Config();
            }
        }
        else
        {
            return null;
        }
    }
}

public class UserClass
{
    public string Name;
    public string Login;
    public string Password;
    public PCMS2 PermissionsList; // OR new PCMS1, as I will explain in a bit

    public UserClass()
    {
        this.Name = "Admin";
        this.Login = "61-64-6D-69-6E";
        this.Password = "61-64-6D-69-6E";
        this.PermissionsList = new PCMS2(); // OR new PCMS1, as I will explain in a bit

    }
}

有问题的一点:考虑 PCMS 类的两个实现,PCMS1 和 PCMS2:

public class PCMS1
{
    public PermissionObject p1, p2;

    public PCMS1()
    {
        p1 = new PermissionObject("ImportConfigCMS", "tsmiImportCMSConfigFile", true);
        p2 = new PermissionObject("ExportConfigCMS", "tsmiExportCMSConfigFile", true);
    }
}

public class PCMS2
{
    public List<PermissionObject> listOfPermissions = new List<PermissionObject>();

    public PCMS2()
    {
        listOfPermissions.Add(new PermissionObject("ImportConfigCMS", "tsmiImportCMSConfigFile", true));
        listOfPermissions.Add(new PermissionObject("ExportConfigCMS", "tsmiExportCMSConfigFile", true));
    }
}

最后是主类:

public partial class Form1 : Form
{
    private Config Con;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Con = Config.Load();
        if (Con == null)
        {
            Con = new Config();
            Con.cmsDataPath = @"E:\testconpcms.xml";
            Con.Save();
        }
        if (Con.usersCMS.Count == 0)
        {
            UserClass adminDefault = new UserClass();
            Con.usersCMS.Add(adminDefault);
            Con.Save();
        }
    }
}

现在,使用PCMS1PCMS2,配置文件会正确生成 - 一个用户拥有 2 个权限。

但是,当存在配置文件时,在主类中调用 Con = Config.Load() 会产生不同的结果。

使用PCMS1Con 对象符合预期 - 1 个用户拥有 2 个权限。

但是,使用 PCMS2Con 对象是 1 个具有 4(四)个权限的用户。它使该字段加倍(基本上是 p1、p2、p1、p2)。在Load()之后放一个BP来看看Con。

我猜列表 (PCMS2) 实现在加载过程中做了一些我不知道的事情,但我似乎找不到问题。

【问题讨论】:

    标签: c# .net xml list xmlserializer


    【解决方案1】:

    您在PMCS2 的构造函数中创建您的权限对象,您也在PMCS1 的构造函数中创建权限对象,但是您确实有两个属性将被序列化程序覆盖。 在PMCS2 的情况下,您的构造函数将两个项目添加到 List 中,然后序列化程序将其反序列化的项目添加到同一个列表中。

    我不完全了解您的用例,但我建议将权限的 init 移至分离方法:

    public class PCMS1
    {
        public PermissionObject p1, p2;
    
        public void Init()
        {
            p1 = new PermissionObject("ImportConfigCMS", "tsmiImportCMSConfigFile", true);
            p2 = new PermissionObject("ExportConfigCMS", "tsmiExportCMSConfigFile", true);
        }
    }
    
    public class PCMS2
    {
        public List<PermissionObject> listOfPermissions = new List<PermissionObject>();
    
        public void Init()
        {
            listOfPermissions.Add(new PermissionObject("ImportConfigCMS", "tsmiImportCMSConfigFile", true));
            listOfPermissions.Add(new PermissionObject("ExportConfigCMS", "tsmiExportCMSConfigFile", true));
        }
    }
    

    之后你可以调用它,如果你想获得初始设置:

    if (Con.usersCMS.Count == 0)
    {
        UserClass adminDefault = new UserClass();
        adminDefault.PermissionsList.Init();
        Con.usersCMS.Add(adminDefault);
        Con.Save();
    }
    

    【讨论】:

    • 当我运行它以生成配置文件时,这似乎会生成空的权限列表。
    • @Janushoff 抱歉,误解了你的代码,我用正确的地方更新了答案来调用 init
    • 是的,这现在可以正常工作了,尽管我仍然有一些困难,为什么它一开始就不能工作。
    • @Janushoff eh 对象的 cosntructor 被序列化程序调用,如果您在 PCMS2 的构造函数中放置断点,您可以看到它,因此构造函数将 2 个项目添加到列表中,然后序列化程序将 2 个项目添加到列表。最后你有 4 个项目。
    猜你喜欢
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多