Десериализовать простой объект массива XML в C# для службы WCF

Уже 3 дня сталкиваюсь с одной и той же проблемой и не могу понять что делаю не так.

Контекст: я создаю новую службу WCF для фиксированного XML.

Проблема: похоже, что десериализация XML идет не так. Я возвращаю объект data, но без заполнения свойства items.

Пробовал до сих пор:

  • Создание класса C# с помощью xsd 4.0 (в настоящее время используется в проекте WCF) и 4.7.
  • Добавление нескольких атрибутов, таких как:

    [ServiceContract(Namespace = "urn:oasis:names:tc:SPML:2:0"), XmlSerializerFormat].
    [System.Xml.Serialization.XmlArrayItemAttribute("attr", IsNullable = false)] 
    

    к собственности Items

Это xml, который я собираюсь получить:

<spml:data xmlns:spml="urn:oasis:names:tc:SPML:2:0">
    <attr name="mailone" xmlns="urn:oasis:names:tc:DSML:2:0:core">
        <value>[email protected]</value>
    </attr>
    <attr name="mailtwo" xmlns="urn:oasis:names:tc:DSML:2:0:core">
        <value>[email protected]</value>
    </attr>
    <attr name="mailthree" xmlns="urn:oasis:names:tc:DSML:2:0:core">
        <value>[email protected]</value>
    </attr>
</spml:data>

С xsd (4.0 в настоящее время используется в проекте wcf для других объектов) я получаю этот класс С# из xsd:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.33440.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:oasis:names:tc:SPML:2:0")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:oasis:names:tc:SPML:2:0", IsNullable = false)]
public partial class data
{
    private attr[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("attr")]
    public attr[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:oasis:names:tc:SPML:2:0")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:oasis:names:tc:SPML:2:0", IsNullable = false)]
public partial class attr
{

    private string valueField;

    private string nameField;

    /// <remarks/>
    public string value
    {
        get
        {
            return this.valueField;
        }
        set
        {
            this.valueField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }
}

Я написал эту программу, чтобы упростить задачу отображения:

using System;
using System.Xml;
using System.Xml.Serialization;

namespace XmlDeserializer
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlSerializer ser = new XmlSerializer(typeof(data));
            data data;

            using (XmlReader reader = XmlReader.Create(PATH))
            {
                data = (data)ser.Deserialize(reader);
            }
        }
    }
}

Если вы запустите это консольное приложение с классом C# в том же проекте и выполните отладку данных, вы получите объект данных обратно с items = null.

Может кто-то направил меня в правильном направлении?

РЕДАКТИРОВАТЬ: это связано с пространствами имен: я удалил все пространства имен в объекте XML и С#, и это сработало.

С уважением, Питер


person Pieter    schedule 21.10.2019    source источник


Ответы (1)


Следующий код работает. Я изменил пространства имен:

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

namespace ConsoleApplication137
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(data));
            data d = (data)serializer.Deserialize(reader);
        }

    }
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:oasis:names:tc:SPML:2:0", IsNullable = false)]
    public partial class data
    {
        private attr[] itemsField;

        /// <remarks/>
        [XmlElement(ElementName = "attr", Namespace = "urn:oasis:names:tc:DSML:2:0:core")]
        public attr[] Items
        {
            get
            {
                return this.itemsField;
            }
            set
            {
                this.itemsField = value;
            }
        }
    }

    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:oasis:names:tc:DSML:2:0:core", IsNullable = false)]
    public partial class attr
    {

        private string valueField;

        private string nameField;

        /// <remarks/>
        public string value
        {
            get
            {
                return this.valueField;
            }
            set
            {
                this.valueField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string name
        {
            get
            {
                return this.nameField;
            }
            set
            {
                this.nameField = value;
            }
        }
    }

}
person jdweng    schedule 21.10.2019
comment
Я только что проверил это, и это сработало. К моему удивлению, я преобразовал свой xml в класс с помощью специальной вставки в VisualStudio, и это дало мне класс, который также работал. Что-то было напутано в инструменте xsd. Что я узнал: я полностью доверял сгенерированному файлу xsd и не думал, что это ошибка. В следующий раз я буду более критичен... Спасибо за помощь - person Pieter; 21.10.2019