c # xml отсутствует элемент во вложенных классах - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть небольшая проблема, которая мучила мою голову в течение нескольких дней. Я пишу что-то вроде ясли для виртуальной гоночной лиги. Я хочу сохранить все свои данные в одном XML-файле, чтобы к нему можно было легко получить доступ с нескольких сторон. Однако из-за ограничения xml-сериализатора 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>

Как видите, элемент Создать комментария просто отсутствует.

1 Ответ

0 голосов
/ 17 ноября 2018

Я нашел проблему.При добавлении объекта комментария через интерфейс changenotification не берется и теряется.В моем полном коде проблема была немного более замаскирована, потому что я использовал отражение, чтобы автоматически установить все свойства.Однако я смотрел только на основной тип интерфейса, а не на все реализованные.Я изменил код, и теперь он работает нормально.Спасибо за поддержку, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...