嵌套类中的C#xml缺少元素

时间:2018-11-16 06:17:46

标签: c# xml serialization

我有一个小问题困扰了我几天。我正在为虚拟赛车联赛编写一种管理工具。 我想将所有数据保存到单个xml文件中,以便可以轻松地从多个方进行访问。 但是,由于xml-serializer的限制,id必须将我所有的类都公开。为此,我编写了一个界面 通过这种方式,我想将原始的管理对象(具有所有功能)转换为包含要进行xml序列化的对象的原始数据。

为了能够跟踪谁创建/更改了所有相关内容,需要持有“ ChangeNotification”字段。 为此,我使用这些字段创建了一个基类,并从中派生了我的容器类。

现在问题来了:如果我只序列化其中一部分,那么一切都很好。但是,一旦我序列化了一个包含另一个从相同基数派生的对象的对象, 我的“ CreateChangeNotification”将仅出现在顶部的对象中。

我不知道为什么这样做,因为显然有两个实例保存在对象中,同时具有不同的值。

很抱歉,很长的代码段,但这就是我需要重新创建问题的地方,并且似乎每次使用此结构都会发生。

[Serializable()]
public class DataManagerXmlContainer<DataContainerType> : IDataManagerContainer
{
    [XmlElement("Created")]
    public ChangeNotificationXmlContainer created;

    [XmlIgnore()]
    public IChangeNotificationDataContainer Created { get => created; set => created = new ChangeNotificationXmlContainer(value); }

    //[XmlElement("Changed")]
    //public ChangeNotificationXmlContainer changed;

    //[XmlIgnore()]
    //public IChangeNotificationDataContainer LastChange { get => changed; set => changed = new ChangeNotificationXmlContainer(value); }

    public DataManagerXmlContainer() { }
}

[Serializable()]
public class ReviewDataXmlContainer : DataManagerXmlContainer<IReviewDataContainer>, IReviewDataContainer
{
    [XmlArray("CommentList")]
    [XmlArrayItem("Comment")]
    public List<ReviewCommentXmlContainer> comments = new List<ReviewCommentXmlContainer>();
    [XmlIgnore()]
    public ICollection<IReviewCommentDataContainer> Comments
    {
        get => comments.Cast<IReviewCommentDataContainer>().ToList();
        set => comments = value.ToList().ConvertAll(x => new ReviewCommentXmlContainer(x));
    }

    public ReviewDataXmlContainer() { }

    public ReviewDataXmlContainer(string authorID)
    {
        created = new ChangeNotificationXmlContainer(authorID, DateTime.Now);
    }

    public void AddComment(IReviewCommentDataContainer comment)
    {
        comments.Add(new ReviewCommentXmlContainer(comment));
    }
}

[Serializable()]
public class ReviewCommentXmlContainer : DataManagerXmlContainer<IReviewCommentDataContainer>, IReviewCommentDataContainer
{
    [XmlAttribute("author_id")]
    public string AuthorAdminID { get; set; }
    public string Text { get; set; }

    public ReviewCommentXmlContainer() { }

    public ReviewCommentXmlContainer(string authorID, string text)
    {
        created = new ChangeNotificationXmlContainer(authorID, DateTime.Now);
        AuthorAdminID = authorID;
        Text = text;
    }

    public ReviewCommentXmlContainer(IReviewCommentDataContainer dataContainer)
    {
        AuthorAdminID = dataContainer.AuthorAdminID;
        Text = dataContainer.Text;
    }
}

[Serializable()]
public class ChangeNotificationXmlContainer : IChangeNotificationDataContainer
{
    [XmlAttribute("author_id")]
    public string AuthorID { get; set; }

    [XmlAttribute("time")]
    public DateTime Time { get; set; }

    public ChangeNotificationXmlContainer() { }

    public ChangeNotificationXmlContainer(string id, DateTime time)
    {
        AuthorID = id;
        Time = time;
    }

    public ChangeNotificationXmlContainer(IChangeNotificationDataContainer dataContainer)
    {
        AuthorID = dataContainer.AuthorID;
        Time = dataContainer.Time;
    }
}

public interface IChangeNotificationDataContainer
{
    string AuthorID { get; set; }
    DateTime Time { get; set; }
}

public interface IDataManagerContainer
{
    IChangeNotificationDataContainer Created { get; set; }
}

public interface IReviewDataContainer : IDataManagerContainer
{
    ICollection<IReviewCommentDataContainer> Comments { get; set; }
    void AddComment(IReviewCommentDataContainer comment);
}

public interface IReviewCommentDataContainer : IDataManagerContainer
{
    string AuthorAdminID { get; set; }
    string Text { get; set; }
}

以及程序代码:

class Program
{
    static void Main(string[] args)
    {
        IReviewCommentDataContainer comment = new ReviewCommentXmlContainer("12345", "This is a test");
        Task.Delay(1000).Wait();
        ReviewDataXmlContainer review = new ReviewDataXmlContainer("23456");
        review.AddComment(comment);


        XmlSerializer serializer = new XmlSerializer(typeof(ReviewDataXmlContainer));
        TextWriter writer = new StreamWriter("Test.xml");
        serializer.Serialize(writer, review);

        //Task.Delay(-1).Wait();
    }
}

这是我的xml的样子:

<?xml version="1.0" encoding="utf-8"?>
<ReviewDataXmlContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Created author_id="23456" time="2018-11-16T06:56:16.5425819+01:00" />
    <CommentList>
        <Comment author_id="12345">
            <Text>This is a test</Text>
        </Comment>
    </CommentList>
</ReviewDataXmlContainer>

您可以看到Comment的Create元素只是丢失。

1 个答案:

答案 0 :(得分:0)

我发现了问题。通过界面添加注释对象时,changenotification不会被带走并丢失。 在我完整的代码中,如果我使用反射来自动设置所有属性,则问题会更加隐蔽。 但是,我只查看主接口类型,而不是所有已实现的接口类型。 我更改了代码,现在可以正常工作了。 谢谢您的支持。