如何使用XmlSerializer使用DefaultValueAttribute序列化属性?

时间:2018-07-17 13:26:30

标签: c# xml attributes xmlserializer xmlwriter

我正在使用XmlSerializer将C#对象序列化为XML。我在尝试序列化的类的某些属性上有DefaultValueAttribute,当我尝试对其进行序列化时,如果XmlSerializer等于默认值,则似乎不包含xml中的值。 看这个例子:

using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Test
{
    public class Person
    {
        [System.Xml.Serialization.XmlAttribute()]
        [System.ComponentModel.DefaultValue("John")]
        public string Name { get; set; }
    }

    public static class Test
    {
        public static void Main()
        {
            var serializer = new XmlSerializer(typeof(Person));
            var person = new Person { Name = "John" };

            using (var sw = new StringWriter())
            {
                using (var writer = XmlWriter.Create(sw))
                {
                    serializer.Serialize(writer, person);
                    var xml = sw.ToString();
                }
            }
        }
    }
}

它将生成以下xml(通知名称属性不可用):

<?xml version="1.0" encoding="utf-16"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

我无法修改类的源代码,因此无法删除DefaultValueAttribute。有没有一种方法可以使XmlSerializer序列化此属性而不更改源代码?

1 个答案:

答案 0 :(得分:3)

您可以通过如下创建时将HttpResponseMessage实例传递到var myCustomException = context.Exception as MyCustomException; if (myCustomException != null) { context.Result = context.Request.CreateResponse(myCustomException.StatusCode, myCustomException.Error); return; } context.Result = context.Request.CreateResponse(HttpStatusCode.InternalServerError, new MyCustomError("Something went wrong")); 来实现。您可以使用此选项将默认值更改为其他值,或将其设置为null以有效地将其删除。

XmlAttributeOverrides

更新:以上内容意味着您必须在要更改的每个属性上再次提供其他不相关的属性。如果您有很多属性,并且只想删除所有属性的默认属性,那么这会有些麻烦。下面的类可用于保留其他自定义属性,而仅删除一种类型的属性。如果只需要对某些属性等进行扩展,则可以进一步扩展。

XmlSerializer

用法:

XmlAttributeOverrides attributeOverrides = new XmlAttributeOverrides();

var attributes = new XmlAttributes()
{
    XmlDefaultValue = null,
    XmlAttribute = new XmlAttributeAttribute()
};

attributeOverrides.Add(typeof(Person), "Name", attributes);

var serializer = new XmlSerializer(typeof(Person), attributeOverrides);
var person = new Person { Name = "John" };

using (var sw = new StringWriter())
{
    using (var writer = XmlWriter.Create(sw))
    {
        serializer.Serialize(writer, person);
        var xml = sw.ToString();
    }
}