Десериализация объекта из XML в C# с производными классами - PullRequest
3 голосов
/ 28 февраля 2020

У меня есть очень простой XML файл ниже:

<Job Name="test">
    <Pages>
        <MainPage Name="page1"/>
    </Pages>
</Job>

'MainPage' является производным классом PageBase, с моей структурой классов, как показано ниже

public class Job
{
    [XmlAttribute]
    public string Name { get; set; }

    [XmlElement]
    public List<PageBase> Pages { get; set; }
}

[XmlInclude(typeof(MainPage))]
[XmlInclude(typeof(SubPage))]
public abstract class PageBase
{
    [XmlAttribute]
    public string Name { get; set; }        
}

public class MainPage : PageBase
{

}

public class SubPage : PageBase
{

}

И здесь это пример кода, который я использую для десериализации:

var xml = "<Job Name=\"test\"><Pages><MainPage Name=\"page1\"></MainPage></Pages></Job>";
MemoryStream str = new MemoryStream();
StreamWriter writer = new StreamWriter(str);
writer.Write(xml);
writer.Flush();
str.Position = 0;

var serializer = new XmlSerializer(typeof(Job));
var job = (Job)serializer.Deserialize(str);

Однако я получаю следующую ошибку - несмотря на включение моего XmlInclude в тип PageBase. Что я делаю неправильно? DotNetFiddle здесь: https://dotnetfiddle.net/UucVmX

Исключение во время выполнения (строка 18): в документе XML есть ошибка (1, 19).

Отслеживание стека:

[System.InvalidOperationException: указанный тип является абстрактным: name = 'PageBase', namespace = '', at.] В Microsoft. Xml .Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read4_PageBase ( Boolean isNullable, Boolean checkType) в Microsoft. Xml .Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read5_Job (Boolean isNullable, Boolean checkType) в Microsoft. Xml .Serialization.GeneratedAssembly.XmlS21_Reader_XJ (1021) Reader Reader. System.InvalidOperationException: Ошибка в XML документе (1, 19).] В System. Xml .Serialization.XmlSerializer.Deserialize (XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
в System. Xml .Serialization.XmlSerializer.Deserialize (Stream stream)
в Program.Main (): строка 18

1 Ответ

0 голосов
/ 28 февраля 2020

Измените XML на:

<Job Name="test">
    <Pages>
        <PageBase xsi:type="MainPage" Name="page1"/>
    </Pages>
</Job>

Попробуйте сначала сериализовать ваш объект и проверьте XML, который он производит. Вы должны увидеть, что XML -элементом будут PageBase и xsi: type = "MainPage".

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