Как я могу использовать файл, который генерируется xsd.exe в универсальном приложении Windows 10

Я генерирую файлы.cs из файлов.xsd, используя xsd.exe. Но когда я добавлял файлы в универсальное пустое приложение Windows 10, я получал сообщение об ошибке "отсутствует ссылка на сборку" для System.SerializableAttribute() и System.ComponentModel.DesignerCategoryAttribute(‌ "‌ code"). Я исправил это с помощью трюка @t.ouvre. Тогда не было ошибок ни в одной конкретной строке кода, но когда я строю код, я получаю сообщение о том, что "Не удается найти тип System.ComponentModel.MarshalByValueComponent в модуле System.dll", и он не указывает точно где ошибка. Как я могу использовать файл, созданный xsd.exe в универсальном приложении Windows 10? Что все, что мне нужно сделать с файлом, чтобы использовать его для сериализации и десериализации (с использованием DataContractSerializer в UWP)

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class request
{

    private usertype userField;

    private string versionField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public usertype user
    {
        get
        {
            return this.userField;
        }
        set
        {
            this.userField = value;
        }
    }

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

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class usertype
{

    private string emailField;

    private string passwordField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string email
    {
        get
        {
            return this.emailField;
        }
        set
        {
            this.emailField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string password
    {
        get
        {
            return this.passwordField;
        }
        set
        {
            this.passwordField = value;
        }
    }
}


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class NewDataSet
{

    private request[] itemsField;

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

2 ответа

Решение

Вы можете подделать отсутствующие классы (System.SerializableAttribute(),System.ComponentModel.DesignerCategoryAttribute), просто добавьте новые файлы с определениями этих классов:

namespace System
{
    internal class SerializableAttribute : Attribute
    {
    }
}
namespace System.ComponentModel
{
    internal class DesignerCategoryAttribute : Attribute
    {
        public DesignerCategoryAttribute(string _) { }
    }
}

для сериализации и десериализации вы должны использовать System.Runtime.Serialization.DataContractSerializer. Например:

DataContractSerializer serializer = new DataContractSerializer(typeof(request));
var r = new request { version = "test" };

using (MemoryStream ms = new MemoryStream())
{
    serializer.WriteObject(ms, r);
    ms.Seek(0, SeekOrigin.Begin);
    using (var sr = new StreamReader(ms))
    {
        string xmlContent = sr.ReadToEnd();
        Debug.WriteLine(xmlContent);
        ms.Seek(0, SeekOrigin.Begin);
        using (XmlReader reader = XmlReader.Create(sr))
        {
            var deserialized = serializer.ReadObject(reader) as request;
            if (deserialized != null && deserialized.version == r.version)
            {
                Debug.WriteLine("ok");
            }
        }
    }
}

SerializableAttribute() и DesignerCategoryAttribute не поддерживаются в приложениях uwp.

Чтобы создать успешный класс, который можно скопировать непосредственно в AP UWP, используйте следующий совет:

Это делается в приложении UWP, поэтому вы можете просто сделать это. Ну, у XML-сериализации есть некоторые ограничения: у вас должен быть конструктор по умолчанию без каких-либо параметров.

если вы планируете сериализовать класс, у которого нет конструктора, Microsoft рекомендует использовать DataContractSerializer для таких случаев использования.

Теперь код довольно прост

  1. Сначала создайте экземпляр объекта для сериализации.
  2. Создайте новый объект XmlSerializer.
  3. Затем XmlWriter obj, так как он принимает много разных классов писателей, и вам нужно создать экземпляр, который я выбрал для создания строк в демонстрационных целях.
  4. Затем просто вызовите serialize на сериализаторе obj, передающем ваш объект obj, а xmlwriter и xml writer выдают op в строителе строк obj.
  5. Затем я просто превращаю его в строку.. отсюда вы можете делать что угодно с xml .. сохранить его или поиграть с ним..
  6. последний метод toUpper был только что добавлен bcoz мне нужна была строка для точки отладки.. это вовсе не обязательно...

              private void Button_Click( object sender , RoutedEventArgs e )
                    {
                        Animal a = new Animal("Sheep" , 4);
                        XmlSerializer m = new XmlSerializer(typeof(Animal));
                        StringBuilder op = new StringBuilder();
                        var x = XmlWriter.Create(op);
                        m.Serialize(x , a);
    
                        string s = op.ToString();
    
                        var p = s.ToUpper();
                    }
    
                    public class Animal
                    {
                        public Animal( string name , int legcount )
                        {
                            this.name = name;
                            this.legcount = legcount;
                        }
    
                        public Animal()
                        {
                            this.name = "default";
                            this.legcount = 10000000;
                        }
    
                        public string name { get; set; }
                        public int legcount { get; set; }
                    }
    

Результат Сериализованного класса

  <?xml version="1.0" encoding="utf-16"?>
    <Animal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <name>Sheep</name>
    <legcount>4</legcount>
    </Animal>

ОБНОВЛЕНИЕ: С помощью этого метода вы можете сначала скопировать все ваши сериализованные классы в приложение и десериализовать их при необходимости внутри приложения.

Теперь все, что вам нужно сделать, это скопировать ваш xml в новое приложение и осуществить десерилизацию, используя те же методы, которые я показал выше.

Другие вопросы по тегам