Как преобразовать XML-документ HTTP-ответа в объект на С#?

Я хочу преобразовать XML-документ HTTP-ответа в объект.

Когда я пытался десериализовать, я получаю сообщение об ошибке, например

Произошло необработанное исключение типа «System.InvalidOperationException» в System.Xml.dll.

Дополнительная информация: Ошибка в XML-документе (1, 2).

Вот мой файл класса

namespace Salcomp.SerialNumberStatus
{
using System;
using System.Diagnostics;
using System.Xml.Serialization;
using System.Collections;
using System.Xml.Schema;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Collections.Generic;

public partial class OperationTypes
{

    private List<OperationType> operationTypeField;

    private static System.Xml.Serialization.XmlSerializer serializer;

    public OperationTypes()
    {
        this.operationTypeField = new List<OperationType>();
    }

    public List<OperationType> OperationType
    {
        get
        {
            return this.operationTypeField;
        }
        set
        {
            this.operationTypeField = value;
        }
    }

    private static System.Xml.Serialization.XmlSerializer Serializer
    {
        get
        {
            if ((serializer == null))
            {
                serializer = new System.Xml.Serialization.XmlSerializer(typeof(OperationTypes));
            }
            return serializer;
        }
    }

    #region Serialize/Deserialize
    /// <summary>
    /// Serializes current OperationTypes object into an XML document
    /// </summary>
    /// <returns>string XML value</returns>
    public virtual string Serialize()
    {
        System.IO.StreamReader streamReader = null;
        System.IO.MemoryStream memoryStream = null;
        try
        {
            memoryStream = new System.IO.MemoryStream();
            Serializer.Serialize(memoryStream, this);
            memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            streamReader = new System.IO.StreamReader(memoryStream);
            return streamReader.ReadToEnd();
        }
        finally
        {
            if ((streamReader != null))
            {
                streamReader.Dispose();
            }
            if ((memoryStream != null))
            {
                memoryStream.Dispose();
            }
        }
    }

    /// <summary>
    /// Deserializes workflow markup into an OperationTypes object
    /// </summary>
    /// <param name="xml">string workflow markup to deserialize</param>
    /// <param name="obj">Output OperationTypes object</param>
    /// <param name="exception">output Exception value if deserialize failed</param>
    /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
    public static bool Deserialize(string xml, out OperationTypes obj, out System.Exception exception)
    {
        exception = null;
        obj = default(OperationTypes);
        try
        {
            obj = Deserialize(xml);
            return true;
        }
        catch (System.Exception ex)
        {
            exception = ex;
            return false;
        }
    }

    public static bool Deserialize(string xml, out OperationTypes obj)
    {
        System.Exception exception = null;
        return Deserialize(xml, out obj, out exception);
    }

    public static OperationTypes Deserialize(string xml)
    {
        System.IO.StringReader stringReader = null;
        try
        {
            stringReader = new System.IO.StringReader(xml);
            return ((OperationTypes)(Serializer.Deserialize(System.Xml.XmlReader.Create(stringReader))));
        }
        finally
        {
            if ((stringReader != null))
            {
                stringReader.Dispose();
            }
        }
    }

    /// <summary>
    /// Serializes current OperationTypes object into file
    /// </summary>
    /// <param name="fileName">full path of outupt xml file</param>
    /// <param name="exception">output Exception value if failed</param>
    /// <returns>true if can serialize and save into file; otherwise, false</returns>
    public virtual bool SaveToFile(string fileName, out System.Exception exception)
    {
        exception = null;
        try
        {
            SaveToFile(fileName);
            return true;
        }
        catch (System.Exception e)
        {
            exception = e;
            return false;
        }
    }

    public virtual void SaveToFile(string fileName)
    {
        System.IO.StreamWriter streamWriter = null;
        try
        {
            string xmlString = Serialize();
            System.IO.FileInfo xmlFile = new System.IO.FileInfo(fileName);
            streamWriter = xmlFile.CreateText();
            streamWriter.WriteLine(xmlString);
            streamWriter.Close();
        }
        finally
        {
            if ((streamWriter != null))
            {
                streamWriter.Dispose();
            }
        }
    }

    /// <summary>
    /// Deserializes xml markup from file into an OperationTypes object
    /// </summary>
    /// <param name="fileName">string xml file to load and deserialize</param>
    /// <param name="obj">Output OperationTypes object</param>
    /// <param name="exception">output Exception value if deserialize failed</param>
    /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
    public static bool LoadFromFile(string fileName, out OperationTypes obj, out System.Exception exception)
    {
        exception = null;
        obj = default(OperationTypes);
        try
        {
            obj = LoadFromFile(fileName);
            return true;
        }
        catch (System.Exception ex)
        {
            exception = ex;
            return false;
        }
    }

    public static bool LoadFromFile(string fileName, out OperationTypes obj)
    {
        System.Exception exception = null;
        return LoadFromFile(fileName, out obj, out exception);
    }

    public static OperationTypes LoadFromFile(string fileName)
    {
        System.IO.FileStream file = null;
        System.IO.StreamReader sr = null;
        try
        {
            file = new System.IO.FileStream(fileName, FileMode.Open, FileAccess.Read);
            sr = new System.IO.StreamReader(file);
            string xmlString = sr.ReadToEnd();
            sr.Close();
            file.Close();
            return Deserialize(xmlString);
        }
        finally
        {
            if ((file != null))
            {
                file.Dispose();
            }
            if ((sr != null))
            {
                sr.Dispose();
            }
        }
    }
    #endregion
}

public partial class OperationType
{

    private string uriField;

    private string nameField;

    private string numberField;

    private bool activeField;

    private bool activeFieldSpecified;

    private string descriptionField;

    private OperationSetupCalculation setupCalculationField;

    private bool setupCalculationFieldSpecified;

    private string sideField;

    private bool usedForRoutingField;

    private bool usedForSchedulingField;

    private string categoryField;

    private string skillsField;

    private string aaa;

    private static System.Xml.Serialization.XmlSerializer serializer;

    public OperationType()
    {
        this.usedForRoutingField = false;
        this.usedForSchedulingField = false;
    }

    public string Uri
    {
        get
        {
            return this.uriField;
        }
        set
        {
            this.uriField = value;
        }
    }

    public string Name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }

    public string Number
    {
        get
        {
            return this.numberField;
        }
        set
        {
            this.numberField = value;
        }
    }

    public bool Active
    {
        get
        {
            return this.activeField;
        }
        set
        {
            this.activeField = value;
        }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool ActiveSpecified
    {
        get
        {
            return this.activeFieldSpecified;
        }
        set
        {
            this.activeFieldSpecified = value;
        }
    }

    public string Description
    {
        get
        {
            return this.descriptionField;
        }
        set
        {
            this.descriptionField = value;
        }
    }

    public OperationSetupCalculation SetupCalculation
    {
        get
        {
            return this.setupCalculationField;
        }
        set
        {
            this.setupCalculationField = value;
        }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool SetupCalculationSpecified
    {
        get
        {
            return this.setupCalculationFieldSpecified;
        }
        set
        {
            this.setupCalculationFieldSpecified = value;
        }
    }

    public string Side
    {
        get
        {
            return this.sideField;
        }
        set
        {
            this.sideField = value;
        }
    }

    [System.ComponentModel.DefaultValueAttribute(false)]
    public bool UsedForRouting
    {
        get
        {
            return this.usedForRoutingField;
        }
        set
        {
            this.usedForRoutingField = value;
        }
    }

    [System.ComponentModel.DefaultValueAttribute(false)]
    public bool UsedForScheduling
    {
        get
        {
            return this.usedForSchedulingField;
        }
        set
        {
            this.usedForSchedulingField = value;
        }
    }

    public string Category
    {
        get
        {
            return this.categoryField;
        }
        set
        {
            this.categoryField = value;
        }
    }

    public string Skills
    {
        get
        {
            return this.skillsField;
        }
        set
        {
            this.skillsField = value;
        }
    }

    private static System.Xml.Serialization.XmlSerializer Serializer
    {
        get
        {
            if ((serializer == null))
            {
                serializer = new System.Xml.Serialization.XmlSerializer(typeof(OperationType));
            }
            return serializer;
        }
    }

    #region Serialize/Deserialize
    /// <summary>
    /// Serializes current OperationType object into an XML document
    /// </summary>
    /// <returns>string XML value</returns>
    public virtual string Serialize()
    {
        System.IO.StreamReader streamReader = null;
        System.IO.MemoryStream memoryStream = null;
        try
        {
            memoryStream = new System.IO.MemoryStream();
            Serializer.Serialize(memoryStream, this);
            memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            streamReader = new System.IO.StreamReader(memoryStream);
            return streamReader.ReadToEnd();
        }
        finally
        {
            if ((streamReader != null))
            {
                streamReader.Dispose();
            }
            if ((memoryStream != null))
            {
                memoryStream.Dispose();
            }
        }
    }

    /// <summary>
    /// Deserializes workflow markup into an OperationType object
    /// </summary>
    /// <param name="xml">string workflow markup to deserialize</param>
    /// <param name="obj">Output OperationType object</param>
    /// <param name="exception">output Exception value if deserialize failed</param>
    /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
    public static bool Deserialize(string xml, out OperationType obj, out System.Exception exception)
    {
        exception = null;
        obj = default(OperationType);
        try
        {
            obj = Deserialize(xml);
            return true;
        }
        catch (System.Exception ex)
        {
            exception = ex;
            return false;
        }
    }

    public static bool Deserialize(string xml, out OperationType obj)
    {
        System.Exception exception = null;
        return Deserialize(xml, out obj, out exception);
    }

    public static OperationType Deserialize(string xml)
    {
        System.IO.StringReader stringReader = null;
        try
        {
            stringReader = new System.IO.StringReader(xml);
            return ((OperationType)(Serializer.Deserialize(System.Xml.XmlReader.Create(stringReader))));
        }
        finally
        {
            if ((stringReader != null))
            {
                stringReader.Dispose();
            }
        }
    }

    /// <summary>
    /// Serializes current OperationType object into file
    /// </summary>
    /// <param name="fileName">full path of outupt xml file</param>
    /// <param name="exception">output Exception value if failed</param>
    /// <returns>true if can serialize and save into file; otherwise, false</returns>
    public virtual bool SaveToFile(string fileName, out System.Exception exception)
    {
        exception = null;
        try
        {
            SaveToFile(fileName);
            return true;
        }
        catch (System.Exception e)
        {
            exception = e;
            return false;
        }
    }

    public virtual void SaveToFile(string fileName)
    {
        System.IO.StreamWriter streamWriter = null;
        try
        {
            string xmlString = Serialize();
            System.IO.FileInfo xmlFile = new System.IO.FileInfo(fileName);
            streamWriter = xmlFile.CreateText();
            streamWriter.WriteLine(xmlString);
            streamWriter.Close();
        }
        finally
        {
            if ((streamWriter != null))
            {
                streamWriter.Dispose();
            }
        }
    }

    /// <summary>
    /// Deserializes xml markup from file into an OperationType object
    /// </summary>
    /// <param name="fileName">string xml file to load and deserialize</param>
    /// <param name="obj">Output OperationType object</param>
    /// <param name="exception">output Exception value if deserialize failed</param>
    /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
    public static bool LoadFromFile(string fileName, out OperationType obj, out System.Exception exception)
    {
        exception = null;
        obj = default(OperationType);
        try
        {
            obj = LoadFromFile(fileName);
            return true;
        }
        catch (System.Exception ex)
        {
            exception = ex;
            return false;
        }
    }

    public static bool LoadFromFile(string fileName, out OperationType obj)
    {
        System.Exception exception = null;
        return LoadFromFile(fileName, out obj, out exception);
    }

    public static OperationType LoadFromFile(string fileName)
    {
        System.IO.FileStream file = null;
        System.IO.StreamReader sr = null;
        try
        {
            file = new System.IO.FileStream(fileName, FileMode.Open, FileAccess.Read);
            sr = new System.IO.StreamReader(file);
            string xmlString = sr.ReadToEnd();
            sr.Close();
            file.Close();
            return Deserialize(xmlString);
        }
        finally
        {
            if ((file != null))
            {
                file.Dispose();
            }
            if ((sr != null))
            {
                sr.Dispose();
            }
        }
    }
    #endregion
}

Другой файл:

    namespace Salcomp.SerialNumberStatus
    {
    public partial class Form1 : Form
    {
        MasterDataManagement MDM = new MasterDataManagement("http://localhost:8012/");
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            Salcomp.SerialNumberStatus.OperationType operationType = new Salcomp.SerialNumberStatus.OperationType();

           var test =  MDM.RestGet<Salcomp.SerialNumberStatus.OperationType>("http://localhost/Enterprise/OperationTypes");

        }
    }
}

Десериализовать

public T RestGet<T>(string url)
    {
        if (!url.Contains("http://")) url = _mdmServerUrl + url;
        var xDoc = url.HttpGet();
        var xml = xDoc.ToString();
        return XmlDeserializeFromString<T>(xml);
    }

    private T XmlDeserializeFromString<T>( string objectData)
    {
        return (T)XmlDeserializeFromString(objectData, typeof(T));
    }

    private  object XmlDeserializeFromString( string objectData, Type type)
    {
        XmlSerializer serializer = new XmlSerializer(type);
        object result;

        using (TextReader reader = new StringReader(objectData))
        {
            result = serializer.Deserialize(reader);
        }
        return result;
    }

XML-ответ:

<OperationTypes xmlns="http://www.example.com/aaa/2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <OperationType Uri="http://localhost:8012/Enterprise/OperationTypes/a1d02dac-c454-497b-808d-a619009c7c7e" Name="test" Number="19" Active="true" Description="" SetupCalculation="PerWorkOrder" Side="" />
<OperationType Uri="http://localhost:8012/Enterprise/OperationTypes/07102c89-93e1-499b-980e-a61900cf2217" Name="OT_Prakash" Number="20" Active="false" Description="" SetupCalculation="PerWorkOrder" Side="" />
</OperationTypes>

Я пробовал много ответов в stackoverflow, но не могу их получить.

любая помощь приветствуется.

Заранее спасибо.


person Archana Palani    schedule 03.06.2016    source источник


Ответы (1)


Я предполагаю, что проблема связана с кодировкой и/или спецификацией (маска порядка байтов) в начале XML.

Одна из проблем заключается в том, что в выводе XML отсутствует заголовок XML вместе с информацией о кодировке. Я думаю, что это возвращается к UTF-8.

При этом .NET по умолчанию использует кодировку UTF-16 и при записи в поток/файл добавляет BOM. Спецификация заставляет парсер XML взорваться.

Пожалуйста, проверьте ваш XML-файл в каком-нибудь HEX-редакторе и убедитесь, что в начале XML нет неожиданных невидимых символов.

Вот пример кода сериализации/десериализации XML, который я использовал. Он всегда должен создавать файл XML с кодировкой UTF-8 без спецификации. Кроме того, он должен работать, даже если перед заголовком XML есть спецификация или какой-либо другой мусор.

public class XmlDataSerializer
{
    public string Serialize<T>(T objectValue) where T : class
    {
        var utf8WithoutBom = new UTF8Encoding(false);
        var xmlSerializer = new XmlSerializer(typeof(T));

        var xmlWriterSettings = new XmlWriterSettings
        {
            Indent = true,
            Encoding = utf8WithoutBom
        };

        using (var memoryStream = new MemoryStream())
        {
            using (var writer = XmlWriter.Create(memoryStream, xmlWriterSettings))
            {
                xmlSerializer.Serialize(writer, objectValue);
                return utf8WithoutBom.GetString(memoryStream.ToArray());
            }
        }
    }

    public T Deserialize<T>(string stringValue) where T : class
    {
        var xmlSerializer = new XmlSerializer(typeof(T));

        //hacky way to get rid of BOM for all encodings
        var xmlStart = stringValue.IndexOf("<?xml", StringComparison.Ordinal);
        if (xmlStart > 0)
        {
            stringValue = stringValue.Remove(0, xmlStart);
        }

        using (var stringReader = new StringReader(stringValue))
        {
            using (var xmlReader = XmlReader.Create(stringReader))
            {
                return xmlSerializer.Deserialize(xmlReader) as T;
            }
        }
    }
}
person Kaspars Ozols    schedule 03.06.2016
comment
Я попытался добавить тег заголовка XML вручную, но все равно получаю ту же ошибку. В XML-документе есть ошибка (1, 41). Поэтому я удалил xmlns=---, теперь вышеуказанная ошибка не появляется. но свойства преобразованного объекта не имеют никаких значений из файла XML. - person Archana Palani; 03.06.2016
comment
,можете дать совет. - person Archana Palani; 03.06.2016
comment
Я добавил пример кода. Это не обязательно показывает лучшие практики, но это должно работать для вашего сценария. Код должен легко подстраиваться под ваш существующий код. Кроме того, вам следует подумать об отделении кода объекта от сериализации, потому что сериализация не должна запекаться в объекте, поскольку она может меняться со временем, например, в какой-то момент вы можете захотеть переключиться на JSON. - person Kaspars Ozols; 03.06.2016
comment
Каспарс, спасибо, попробую. - person Archana Palani; 03.06.2016