开发者

C# XmlSerializer ignores xs:attribute with types other than xs:string

开发者 https://www.devze.com 2023-02-10 00:39 出处:网络
my problem seems very odd and I did not find any other with that problem, so I guess it is a very simple and stupid mistake, which I can\'t seem to find out.

my problem seems very odd and I did not find any other with that problem, so I guess it is a very simple and stupid mistake, which I can't seem to find out.

I have an XSD, from which I generate a class structure using xsd.exe. I "fill" my object with values, but when serializing it to XML it ignores all class-properties which are not of type string.

var myGraph = new graph();
myGraph.myString = "hallo";
myGraph.myInt = 80;

var serializer = new XmlSerializer(typeof(graph));
TextWriter writeFileStream = new StreamWriter(Path.Combine(outFolder, outFile));
serializer.Serialize(writeFileStream, myGraph);
writeFileStream.Close();

I expected:

<graph xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
    myString="hallo" 
    myInt="80"
/>

The actual output is:

<graph xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    myString="hallo" 
/>

The attribute myInt has been ignored. If I define it as a string, it will also appear, but as any other type it will not show up. If I declare it required and leave it null, it will be serialized as myInt="0".

What am I missing?

Some details:

XSD:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="graph">
    <xs:complexType>
      <xs:attribute name="myString" type="xs:string" />
      <xs:attribute name="myInt" type="xs:int" />
    </xs:complexType>
  </xs:element>
</xs:schema>

generated class:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=false)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class graph {
    private string myStringField;
    private int myIntField;

    [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified)]
    public string myString {
        get { return this.myStringField; }
        set { this.myStringField = value; }
    }

    [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified)]
    public int myIn开发者_StackOverflowt {
        get { return this.myIntField; }
        set { this.myIntField = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool myIntSpecified {
        get { return this.myIntFieldSpecified; }
        set { this.myIntFieldSpecified = value; }
    }


XSD will add an additional "specified" field for all properties that are value types. When using .NET serialization with value types, you will always need to specify the field's value and set the matching "specified" property to true.

Change you code to this and it will work as expected:

var myGraph = new graph();
myGraph.myString = "hallo";
myGraph.myInt = 80;
myGraph.myIntSpecified = true;


I'm not 100% sure about this, but remember something similar. See the generated 'myIntSpecified' field? You should set this to true.

xsd.exe has some big limitations, you could google for alternatives, or simply remember setting it to true every time. :)


There something else going on your side my friend. I did compile the code and it worked perfectly:

class:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class graph
{
    private string myStringField;
    private int myIntField;

    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
    public string myString
    {
        get { return this.myStringField; }
        set { this.myStringField = value; }
    }

    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
    public int myInt
    {
        get { return this.myIntField; }
        set { this.myIntField = value; }
    }


}

Code:

    graph g = new graph() {myInt = 80, myString = "ali"};
    XmlSerializer xss = new XmlSerializer(typeof (graph));
    MemoryStream ms = new MemoryStream();
    xss.Serialize(ms, g);
    StreamReader sb = new StreamReader(ms);
    ms.Position = 0;
    Console.WriteLine(sb.ReadToEnd());

Output:

<graph xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org
/2001/XMLSchema-instance" myString="ali" myInt="80" />
0

精彩评论

暂无评论...
验证码 换一张
取 消