Исключение System.InvalidOperationException не обработано - Сериализация XMl C # - PullRequest
0 голосов
/ 24 января 2010

Я сделал документ XML с использованием XML-сериализации.

Это выглядит так

<?xml version="1.0" encoding="utf-8"?>
<Course xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <courseName>Comp 1510</courseName>
  <backgroundColor>#ffffff</backgroundColor>
  <fontColor>#ffffff</fontColor>
  <sharingKey>ed35d1f8-6be1-4f87-b77f-c70298e5abbb</sharingKey>
  <task type="Assignment">
    <taskName>First Task</taskName>
    <description>description</description>
    <taskDueDate>2010-01-24T12:41:20.0321826-08:00</taskDueDate>
    <weight xsi:nil="true" />
    <beforeDueDateNotification>30</beforeDueDateNotification>
    <outOf>50.4</outOf>
  </task>
</Course>

Мой код, чтобы сделать это

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    [XmlRoot("Course")]
    public class MyWrapper 
    {
        public MyWrapper()
        {
            TaskList = new List<Tasks>();
        }

        [XmlElement("courseName")]
        public string CourseName { get; set; }

        [XmlElement("backgroundColor")]
        public string BackgroundColor { get; set; }

        [XmlElement("fontColor")]
        public string  FontColor { get; set; }

        [XmlElement("sharingKey")]
        public Guid SharingKey { get; set; }

        [XmlElement("task")]
        public List<Tasks> TaskList { get; set; }

    }

public class Tasks
{
    [XmlAttribute("type")]
    public string Type { get; set; }

    [XmlElement("taskName")]
    public string TaskName { get; set; }

    [XmlElement("description")]
    public string Description { get; set; }

    [XmlElement("taskDueDate")]
    public DateTime TaskDueDate { get; set; }

    [XmlElement("weight")]
    public decimal? Weight { get; set; }

    [XmlElement("beforeDueDateNotification")]
    public int BeforeDueDateNotification { get; set; }

    [XmlElement("outOf")]
    public decimal? OutOf { get; set; }

}

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            MyWrapper wrap = new MyWrapper();
            wrap.CourseName = "Comp 1510";
            wrap.FontColor = "#ffffff";
            wrap.BackgroundColor = "#ffffff";
            wrap.SharingKey = Guid.NewGuid();

            Tasks task = new Tasks()
            {
                TaskName = "First Task",
                Type = "Assignment",
                TaskDueDate = DateTime.Now,
                Description = "description",
                BeforeDueDateNotification = 30,
                OutOf = 50.4M
            };

            wrap.TaskList.Add(task);
            SerializeToXML(wrap);

           var grab = DeserializeFromXML();

           foreach (var item in grab)
           {

           }
        }

        static public void SerializeToXML(MyWrapper list)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));
            TextWriter textWriter = new StreamWriter(@"C:\New folder\test.xml");
            serializer.Serialize(textWriter, list);
            textWriter.Close();
        }

        static List<MyWrapper> DeserializeFromXML()
        {
            XmlSerializer deserializer = new XmlSerializer(typeof(List<MyWrapper>));
            TextReader textReader = new StreamReader(@"C:\New folder\test.xml");
            List<MyWrapper> tasks;
            tasks = (List<MyWrapper>)deserializer.Deserialize(textReader);
            textReader.Close();

            return tasks;
        }
    }
}

Теперь, когда я пытаюсь сериализовать его, я получаю эту ошибку

System.InvalidOperationException was unhandled
  Message="There is an error in XML document (2, 2)."
  Source="System.Xml"
  StackTrace:
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       at System.Xml.Serialization.XmlSerializer.Deserialize(TextReader textReader)
       at ConsoleApplication1.Program.DeserializeFromXML() in C:\Users\chobo2\Desktop\ConsoleApplication1\ConsoleApplication1\Program.cs:line 55
       at ConsoleApplication1.Program.Main(String[] args) in C:\Users\chobo2\Desktop\ConsoleApplication1\ConsoleApplication1\Program.cs:line 34
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.InvalidOperationException
       Message="<Course xmlns=''> was not expected."
       Source="ap72r7cf"
       StackTrace:
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderList1.Read5_ArrayOfMyWrapper()
       InnerException: 

Я не уверен, почему это происходит.

Некоторые дополнительные вопросы - ответьте, пожалуйста, после ответа на основную проблему

Я не хочу делать новое сообщение на форуме для этих 2 вопросов, если только мне не придется.

  1. Почему важно дать ему тип объекта?Например, почему бы не сделать все поля в виде строк?

        [XmlElement("sharingKey")]
        public Guid SharingKey { get; set; }
    

Это только для того, чтобы при сериализации вы получили в этом случае Guid, чтобы потом его не былоВам нужно преобразовать его из строки в Guid?

Если это правильно, как насчет того, если вы получите XML-файл от кого-то другого и захотите его сериализовать, как вы узнаете, какие объекты из него получатся??Например, как вы узнали, что мой «OutOf» на самом деле является типом десятичного числа, допускающего обнуляемость?На самом деле, как C # знает это?Я не вижу ничего такого, что указывало бы на то, что это тип.

Когда я получаю сериализацию, мне интересно, как мне сделать цикл foreach.Так как я хочу пройтись по каждому списку объектов «MyWrapper».Но в MyWrapper есть коллекция объектов Task.Так нужно ли делать цикл for внутри цикла foreach, чтобы получить его?Или есть способ получше?

Спасибо

Ответы [ 2 ]

1 голос
/ 25 января 2010

Вы пытаетесь сериализовать единственный экземпляр MyWrapper, но затем десериализовать его как список из них. Если вы придерживаетесь одного или другого (в любом случае), он работает нормально. Например:

static public void SerializeToXML(MyWrapper wrapper)
{
    XmlSerializer serializer = new XmlSerializer(typeof(List<MyWrapper>));
    using (TextWriter textWriter = File.CreateText("test.xml"))
    {
        // Create single-element list
        serializer.Serialize(textWriter, new List<MyWrapper>{wrapper});
    }
}

static List<MyWrapper> DeserializeFromXML()
{
    XmlSerializer deserializer = new XmlSerializer(typeof(List<MyWrapper>));
    using (TextReader textReader = File.OpenText("test.xml"))
    {
        return (List<MyWrapper>)deserializer.Deserialize(textReader);
    }
}

или (для одного элемента):

static public void SerializeToXML(MyWrapper wrapper)
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));
    using (TextWriter textWriter = File.CreateText("test.xml"))
    {
        serializer.Serialize(textWriter, wrapper);
    }
}

static MyWrapper DeserializeFromXML()
{
    XmlSerializer deserializer = new XmlSerializer(typeof(MyWrapper));
    using (TextReader textReader = File.OpenText("test.xml"))
    {
        return (MyWrapper)deserializer.Deserialize(textReader);
    }
}

Вы просто должны быть последовательными, вот и все.

1 голос
/ 25 января 2010

Ну, я думаю, проблема в том, что вы сериализуете один MyWrapper, но пытаетесь десериализовать List<MyWrapper>

Это не сработает - вы сериализуете один объект в свой файл, вы возвращаете один объект MyWrapper при десериализации из этого файла.

Измените десериализацию на:

    static MyWrapper DeserializeFromXML()
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(MyWrapper));
        TextReader textReader = new StreamReader(@"C:\New folder\test.xml");
        MyWrapper tasks = (MyWrapper)deserializer.Deserialize(textReader);
        textReader.Close();
        return tasks;
    }

и все должно работать снова.

...