Как я могу использовать файл, который генерируется 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 для таких случаев использования.
Теперь код довольно прост
- Сначала создайте экземпляр объекта для сериализации.
- Создайте новый объект XmlSerializer.
- Затем XmlWriter obj, так как он принимает много разных классов писателей, и вам нужно создать экземпляр, который я выбрал для создания строк в демонстрационных целях.
- Затем просто вызовите serialize на сериализаторе obj, передающем ваш объект obj, а xmlwriter и xml writer выдают op в строителе строк obj.
- Затем я просто превращаю его в строку.. отсюда вы можете делать что угодно с xml .. сохранить его или поиграть с ним..
последний метод 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 в новое приложение и осуществить десерилизацию, используя те же методы, которые я показал выше.