how can i use the file that is generated by xsd.ex

2019-06-22 15:17发布

问题:

I am generating .cs files from .xsd files using xsd.exe. But when I am adding the files to windows 10 universal blank app, I was getting error as "missing an assembly reference" for System.SerializableAttribute() and System.ComponentModel.DesignerCategoryAttribute(‌​"‌​code"). I fixed this by @t.ouvre's trick. Then there were no errors in any of the particular line of the code but when i am building the code i am getting an error saying that " Cannot find type System.ComponentModel.MarshalByValueComponent in module System.dll" and it doesn't specify exactly where the error is. How can I use the file generated by xsd.exe in windows 10 universal app? What are all the things that I need to do with the file to use it for serialization and deserialization (using DataContractSerializer in 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;
        }
    }
}

回答1:

You can fake missing classes (System.SerializableAttribute(),System.ComponentModel.DesignerCategoryAttribute), just add new files with theses classes definitions :

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

for serialization and deserialization, you have to use System.Runtime.Serialization.DataContractSerializer. For example :

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");
            }
        }
    }
}


回答2:

SerializableAttribute() and DesignerCategoryAttribute aren't supported in the uwp apps.

To produce a successful class that can be copied directly into the UWP ap , use the following tip :

This is done in a UWP app so u can just go ahead and do this. Well the XML serialization does have some limitations that is you must have a default constructor without any parameters.

if you are planing to serialize a class that doesn't have a constructor microsoft encourages to use DataContractSerializer for such use cases.

Now the code is quite simple

  1. First instantiate the obj to serialize.
  2. Make a new XmlSerializer object.
  3. Then the XmlWriter obj , since it takes in many different writer classes and u Need to instantiate one i've chosen string builder for demo purposes.
  4. Then just simply call serialize on the serializer obj passing in your obj and the xmlwriter and the xml writer produces the op in the string builder obj.
  5. Then i just turn it into a string.. from here u can do anything with the xml .. save it or play with it ..
  6. the last toUpper method was just added bcoz i needed a line for debug point .. it's not necessary at all ...

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

The reult of the Serialized class

  <?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>

UPDATE: By this method you can first copy all of your serialized classes into the app and deserialize them when necessary inside the app.

Now all you need to do is copy your xml into ur new app and implement deserilization using the same techniques i've shown above.