【问题标题】:how can i use the file that is generated by xsd.exe in windows 10 universal app如何在 Windows 10 通用应用程序中使用由 xsd.exe 生成的文件
【发布时间】:2015-12-22 08:28:52
【问题描述】:

我正在使用 xsd.exe 从 .xsd 文件生成 .cs 文件。但是,当我将文件添加到 Windows 10 通用空白应用程序时,我收到错误,因为 System.SerializableAttribute() 和 System.ComponentModel.DesignerCategoryAttribute(‌​"‌​code") 的“缺少程序集引用”。我通过@t.ouvre 的技巧解决了这个问题。然后在代码的任何特定行中都没有错误,但是当我构建代码时,我收到一条错误消息,提示“在模块 System.dll 中找不到类型 System.ComponentModel.MarshalByValueComponent”并且它没有准确指定错误在哪里。如何在 windows 10 通用应用程序中使用 xsd.exe 生成的文件?我需要对文件执行哪些操作才能将其用于序列化和反序列化(在 UWP 中使用 DataContractSerializer)

/// <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;
        }
    }
}

【问题讨论】:

  • 你能发布一个生成的文件吗?
  • System.SerializableAttribute(),System.ComponentModel.DesignerCategoryAttribute("code") 显示错误为“不存在,缺少程序集引用”。它不会在控制台应用程序中显示任何错误。
  • 可以手动删除非编译属性吗? (System.SerializableAttribute(),System.ComponentModel.DesignerCategoryAttribute("‌​code"))
  • 我有很多文件。手动编辑需要很长时间。但如果没有其他选择,我将不得不这样做。手动删除后,是否需要添加 DataContract 才能使其在序列化过程中正常工作?
  • 抱歉耽搁了,请看我的回复;)

标签: c# serialization win-universal-app xsd.exe windows-10-universal


【解决方案1】:

您可以伪造缺少的类(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");
            }
        }
    }
}

【讨论】:

  • 对不起。我还有一个问题。构建代码时出现以下错误:Xaml Internal Error error WMC9999: Cannot find type System.ComponentModel.MarshalByValueComponent in module System.dll。
  • 您能发布一些与此错误相关的代码(或链接)吗?我认为最后一个错误与以前的错误无关,所以我需要更多信息
  • 我刚刚将我的问题中的代码添加到 UWP。我的项目中只有两个文件(App.xaml.cs、myfile.cs(包含问题中的代码))。根据您给我的想法,我只是跳过了以前的错误。然后我的代码没有错误。但是在编译代码时,我得到“在模块 System.dll 中找不到类型 System.ComponentModel.MarshalByValueComponent”。
  • 它只显示一个错误:“在模块 System.dll 中找不到类型 System.ComponentModel.MarshalByValueComponent”
  • 我指的是名为“Output”的窗口,而不是名为“Error List”的窗口。输出窗口提供了更多详细信息。
【解决方案2】:

SerializableAttribute() 和 DesignerCategoryAttribute uwp 应用程序不支持。

要生成可直接复制到 UWP 应用程序中的成功类,请使用以下提示:

这是在 UWP 应用程序中完成的,因此您可以继续执行此操作。 那么 XML 序列化确实有一些限制,那就是你必须有一个没有任何参数的默认构造函数。

如果您打算序列化一个没有构造函数的类,微软鼓励在此类用例中使用DataContractSerializer

现在代码很简单

  1. 首先实例化要序列化的obj。
  2. 创建一个新的 XmlSerializer 对象。
  3. 然后是 XmlWriter obj,因为它包含许多不同的编写器类,并且您需要实例化一个我选择的字符串生成器用于演示目的。
  4. 然后只需简单地调用序列化程序 obj 上的 serialize,传入您的 obj 和 xmlwriter,然后 xml writer 在字符串生成器 obj 中生成 op。
  5. 然后我把它变成一个字符串.. 从这里你可以用 xml 做任何事情.. 保存它或玩它..
  6. 刚刚添加了最后一个 toUpper 方法,因为我需要一行作为调试点..根本没有必要...

              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 复制到您的新应用中,并使用我上面展示的相同技术实现反序列化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2015-10-28
    • 2020-10-27
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多