是否有 DataContractSerializer 的替代方案,用于 Web API 中的 POST 编组,不会对 XML 元素强加排序?

问题描述

我有一个现有的 Web API 端点,到目前为止,只有通过 JSON 访问时才支持该端点。

也就是说,我们只支持在 content-type 为“application/json”时使用它。我们现在正试图让它接受“application/xml”。

我们已经解决了许多问题,没有在模型上设置 [DataContract],然后没有在模型的 [DataContract] 上指定 namespace="" 等等。但我们已经解决了这个问题,我们现在正确地进行了 XML 编组。 ModelState 有效。

但我们并没有获得所有数据。

我们的控制器操作:

[HttpPost,Route("")]
public HttpResponseMessage PostNoteForTickets([FromBody] IEnumerable<NoteDto> dto)
{
    ...
}

我们的注意事项:

[DataContract(Namespace = "")]
public class NoteDto
{
    [DataMember]
    public string TicketNumber { get; set; }

    [DataMember]
    public string CreatedBy { get; set; }
    
    [DataMember]
    public DateTime? CreatedDateTime { get; set; }
    
    [DataMember]
    public string Contents { get; set; }
}

我们发送的 XML:

<?xml version="1.0"?>
<ArrayOfNoteDto>
    <NoteDto>
        <TicketNumber>TestJob1</TicketNumber>
        <CreatedBy>PostMan</CreatedBy>
        <CreatedDateTime>2020-11-02T13:14:15.678</CreatedDateTime>
        <Contents>This is a note</Contents>
    </NoteDto>
</ArrayOfNoteDto>

正如我所说,这是没有错误的编组

我们的 IEnumerable dto 由包含一个 NoteDto 对象的 NoteDto 数组填充。

那个 NoteDto 对象将 TicketNumber 设置为“TestJob1”,但 CreatedBy、CreatedDateTime 和 Contents 为 null - 当它们在发送的 XML 中绝对不是 null 时。

我已经检查了原始内容

var rawContent = Request.Content.asstring();

并且所有字段都存在于发送到控制器的 XML 中。为什么一个字段被填充而其他字段没有?


继续探索:

如果我在数据契约中指定字段顺序:

[DataContract(Namespace = "")]
public class NoteDto
{
    [DataMember(Order = 1)]
    public string TicketNumber { get; set; }

    [DataMember(Order = 2)]
    public string CreatedBy { get; set; }

    [DataMember(Order = 3)]
    public DateTime? CreatedDateTime { get; set; }

    [DataMember(Order = 4)]
    public string Contents { get; set; }
}

然后以相同的顺序提交 XML 及其元素,所有字段都正确填充。如果我以不同的顺序提交 XML,某些字段最终会为空。

我觉得这是对我们 API 的一个非常不合理的限制。我真的不想告诉我们的客户他们的客户没有工作,因为他们提交的 XML 元素顺序错误

特别是当 XML 不需要元素排序时。在 XML 模式中,可以需要这种东西,但很少需要。

但 Web API 似乎迫使我要求提交到 API 端点的 XML 中的元素排序,无论我是否愿意。

这似乎是一个荒谬的想法,我很犹豫是否真的了解正在发生的事情。

有人有什么想法吗?


另一种探索。

如果我不指定顺序,并按字母顺序提交带有元素的 XML,它们都会按需要填充。如果您不希望按字母顺序排列,则只需在 DataContract 中指定顺序即可。


因此,进一步探索 - 正如 David 在评论中指出的,这特别是 Microsoft 的 DataContractSerializer 的一种行为。

所以这就提出了一个问题 - 是否有 DataContractSerializer 的替代方案可以配置为处理 Web API 编组,而不会对 XML 元素强加排序?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)