C# 使用XmlSerializer序列化默认属性

C# 使用XmlSerializer序列化默认属性,c#,xml-serialization,xmlserializer,C#,Xml Serialization,Xmlserializer,基于post,我尝试创建一个子类XmlTextWriter,它写入所有属性值,甚至是默认值。但我不能让它工作。有人能帮忙吗 下面是我要序列化的类: [System.SerializableAttribute()] [System.Xml.Serialization.XmlType(AnonymousType = true)] [System.Xml.Serialization.XmlRoot(Namespace = "", IsNullable = false)] public class Fo

基于post,我尝试创建一个子类
XmlTextWriter
,它写入所有属性值,甚至是默认值。但我不能让它工作。有人能帮忙吗

下面是我要序列化的类:

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlType(AnonymousType = true)]
[System.Xml.Serialization.XmlRoot(Namespace = "", IsNullable = false)]
public class Foo
{
    public string content { get; set; }

    [System.Xml.Serialization.XmlAttribute()]
    [System.ComponentModel.DefaultValue(true)]
    public bool isActive { get; set; }
}
下面是我创建Foo实例并将其序列化为字符串的代码:

XmlSerializerNamespaces ns = new XmlSerializerNamespaces(
    new XmlQualifiedName[] { new XmlQualifiedName("", "") });
    // I need that for not writing a namespace during serialization
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
Foo f = new Foo();
f.content = "hello";
f.isActive = false;

string fStr;
using (MemoryStream ms = new MemoryStream())
using (XmlWriter wr = new XmlTextWriter(ms, new UTF8Encoding(false)))
{
    serializer.Serialize(wr, f, ns);
    ms.Position = 0;
    using (StreamReader sr = new StreamReader(ms))
    {
        fStr = sr.ReadToEnd();
    }
}
此代码将为
fStr
提供以下内容:

<?xml version="1.0" encoding="utf-8"?><Foo><content>hello</content></Foo>
base.WriteAttributes
的鼠标悬停显示:

在派生类中重写时,写出所有属性 在XmlReader中的当前位置找到

所以我假设总是为
defattr
选择
true
就可以了,但它不会改变输出中的任何内容。我也尝试了
false
,但也不起作用


有什么想法吗?

在您的示例中,您混合了ComponentModel和Serialization注释,但它们似乎没有按预期工作。我浏览了所有我能想到的排列设置,结果出乎意料

var foo = new Foo();
foo.content = "hello";
//foo.isActive is left undefined
Console.WriteLine($"foo.isActive is left undefined");
Console.WriteLine($"foo.isActive = {foo.isActive}");
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
string file = "File.xml";
using (StreamWriter sw = new StreamWriter(file))
{
    serializer.Serialize(sw,foo);
}
bool attExists = File.ReadAllText(file).Contains("isActive");
Console.WriteLine($"It is {attExists} that isActive exists in {file}");
using (StreamReader sr = new StreamReader(file))
{
    Foo test = (Foo)serializer.Deserialize(sr); 
    Console.WriteLine(test.isActive);
}
代码第3行发生更改并反映在测试第一行输出中的结果

foo.isActive is left undefined
foo.isActive = False
It is True that isActive exists in File.xml
False

foo.isActive = true;
foo.isActive = True
It is False that isActive exists in File.xml
False

foo.isActive = false;
foo.isActive = False
It is True that isActive exists in File.xml
False
如果你把你的成绩补充到另一个班级,你在这里的成绩就不会那么好了。似乎注释所做的只是告诉序列化程序如果该值是默认值,则不输出该值

就我个人而言,我会通过在公共构造函数中默认值并同时忽略注释来实现这一点。其目的更加明确,重新设计Xmlserializer是一种非常过分的做法,可能会带来其他意想不到的后果

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlType(AnonymousType = true)]
[System.Xml.Serialization.XmlRoot(Namespace = "", IsNullable = false)]
public class Foo
{
    public string content { get; set; }
    [System.Xml.Serialization.XmlAttribute()]
    public bool isActive { get; set; }
    public Foo()
    {
        isActive = true;
    }
}
运行相同的测试结果会得到更可预测的结果

foo.isActive is left undefined;
foo.isActive = True
It is True that isActive exists in File.xml
True

foo.isActive = true;
foo.isActive = True
It is True that isActive exists in File.xml
True

foo.isActive = false;
foo.isActive = False
It is True that isActive exists in File.xml
False

祝你好运

XmlSerializer
决定序列化什么,而不是
XmlWriter
XmlWriter
及其不推荐的子类
XmlTextWriter
不了解正在序列化的内容。他们将请求的任何内容写入XML。为了强制
XmlSerializer
序列化默认值属性,我找到了和。这两种方法中的任何一种都能充分回答您的问题吗?而且,在任何情况下,都是用于将属性从
XmlReader
复制到
XmlWriter
(例如,它由内部使用),以便在序列化过程中不发挥作用。
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlType(AnonymousType = true)]
[System.Xml.Serialization.XmlRoot(Namespace = "", IsNullable = false)]
public class Foo
{
    public string content { get; set; }
    [System.Xml.Serialization.XmlAttribute()]
    public bool isActive { get; set; }
    public Foo()
    {
        isActive = true;
    }
}
foo.isActive is left undefined;
foo.isActive = True
It is True that isActive exists in File.xml
True

foo.isActive = true;
foo.isActive = True
It is True that isActive exists in File.xml
True

foo.isActive = false;
foo.isActive = False
It is True that isActive exists in File.xml
False