XmlSerializerOutputFormatter 和 XmlDataContractSerializerOutputFormatter 之间的区别

difference between XmlSerializerOutputFormatter and XmlDataContractSerializerOutputFormatter

我想知道这两个序列化器有什么区别。当设置 accept header = application/xml 时。我正在使用普通 DTO 作为 return 值,首选哪个?还有 api 的消费者,他们请求 xml 作为回应应该使用哪个?

正在开发 aspnet 核心网络 api 3.1,构建 restful apis。上述查询中的任何 suggestions/redirects 都会有所帮助。

XmlSerializerOutputFormatter 是一个 asp.net 核心输出格式化程序,它在内部使用 XmlSerializer,而 DataContractSerializerOutputFormatter 在内部使用 DataContractSerializer

DataContractSerializer配置更灵活。例如,它支持引用检测以防止序列化器递归序列化项目,这通常会导致无限循环。

在我自己的项目中,我更喜欢使用 DataContractSerializerOutputFormatter 因为它能够处理私有属性 setter

public string Text { get; private set; }

失败案例

Dtos 项目

namespace DataContractSerializerPOC.Dtos
{
    public class Person
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        // Fullname can only be set from this project
        public string FullName { get; internal set; }
    }

    public class PersonService
    {
        public List<Person> GetPeople()
        {
            // Create a list of people to be serialized
            var people = new List<Person>
            {
                new Person { Id = 1, FirstName = "John", LastName = "Doe" },
                new Person { Id = 2, FirstName = "Jim", LastName = "Flix" },
                new Person { Id = 3, FirstName = "Jack", LastName = "Splick" },
            };
            
            // Set the fullname from this project
            // In some cases you may need to do this, instead of implementing a readonly property
            foreach (var person in people)
                person.FullName = $"{person.FirstName} {person.LastName}";

            return people;
        }
    }
}

控制台项目

namespace DataContractSerializerPOC
{
    class Program
    {
        static void Main(string[] args)
        {
            var personService = new PersonService();
            var people = personService.GetPeople();

            var writer = new StringWriter();
            var serializer = new XmlSerializer(typeof(List<Person>));
            serializer.Serialize(writer, people);
        }
    }
}

结果

DataContractSerializer 的工作案例

Dtos 项目

namespace DataContractSerializerPOC.Dtos
{
    [DataContract]
    public class Person
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }

        // Fullname can only be set from this project
        [DataMember]
        public string FullName { get; internal set; }
    }

    public class PersonService
    {
        ...
    }
}

控制台项目

namespace DataContractSerializerPOC
{
    class Program
    {
        static void Main(string[] args)
        {
            var personService = new PersonService();
            var people = personService.GetPeople();

            var memoryStream = new MemoryStream();
            var serializer = new DataContractSerializer(typeof(List<Person>));
            serializer.WriteObject(memoryStream, people);

            memoryStream.Seek(0, SeekOrigin.Begin);
            var text = new StreamReader(memoryStream).ReadToEnd();
        }
    }
}

结果

因此 DataContractSerializer 能够处理具有私有 setter 的属性,而 XmlSerializer 则不能。