C# Xml序列化在ASP.NET Web Api中未按预期工作

C# Xml序列化在ASP.NET Web Api中未按预期工作,c#,asp.net,xml,serialization,C#,Asp.net,Xml,Serialization,我们有一个Web API,它为所有模型使用一个基类。结构如下 基本抽象类 [DataContract(Namespace = "")] public abstract class Criteria { protected Criteria() { Offset = 0; Limit = 250; } [DataMember(Name = "offset", Order = 97, EmitDefaultValue = false)]

我们有一个Web API,它为所有模型使用一个基类。结构如下

基本抽象类

[DataContract(Namespace = "")]
public abstract class Criteria
{
    protected Criteria()
    {
        Offset = 0;
        Limit = 250;
    }
    [DataMember(Name = "offset", Order = 97, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public int? Offset { get; set; }

    [DataMember(Name = "limit", Order = 98, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public int? Limit { get; set; }
}
[DataContract(Name = "insightCriteria", Namespace = "")]
public class InsightCriteria : Criteria
{
    [DataMember(Name = "geography", Order = 95, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    [JsonConverter(typeof(StringEnumConverter))]
    public InsightGeography Geography { get; set; }
}
这实现了基本抽象类

[DataContract(Namespace = "")]
public abstract class Criteria
{
    protected Criteria()
    {
        Offset = 0;
        Limit = 250;
    }
    [DataMember(Name = "offset", Order = 97, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public int? Offset { get; set; }

    [DataMember(Name = "limit", Order = 98, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public int? Limit { get; set; }
}
[DataContract(Name = "insightCriteria", Namespace = "")]
public class InsightCriteria : Criteria
{
    [DataMember(Name = "geography", Order = 95, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    [JsonConverter(typeof(StringEnumConverter))]
    public InsightGeography Geography { get; set; }
}
进一步实现上述类的实际模型

[DataContract(Name = "jobReportCriteria", Namespace = "")]
public class JobReportCriteria : InsightCriteria
{
    [DataMember(Name = "groupBy", Order = 1, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    [JsonConverter(typeof(StringEnumConverter))]
    public JobReportGroupings GroupBy { get; set; }

    [DataMember(Name = "timePeriod", Order = 2, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public TimePeriod TimePeriod { get; set; }

    [DataMember(Name = "queryString", Order = 3, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public string QueryString { get; set; }

    [DataMember(Name = "includeTotalClassifiedPostings", Order = 4, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public bool IncludeTotalClassifiedPostings { get; set; }

    [DataMember(Name = "includeTotalUnclassifiedPostings", Order = 5, EmitDefaultValue = false)]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public bool IncludeTotalUnclassifiedPostings { get; set; }
}
问题

现在的问题是,当使用json序列化时,一切正常,我在抽象类中接收到offset和limit的值。但是当使用XML序列化时,偏移量和限制不会被填充

下面是我通过Rest客户端传递给api的请求

<jobReportCriteria>
  <groupBy>State</groupBy>
  <timePeriod>
    <from>2014-02-06T00:00:00</from>
    <to>2014-05-06T00:00:00</to>
  </timePeriod>
  <queryString>[nationwide]: &quot; nationwide &quot;</queryString>
  <includeTotalClassifiedPostings>true</includeTotalClassifiedPostings>
  <includeTotalUnclassifiedPostings>true</includeTotalUnclassifiedPostings>
  <includeLastDataDate>true</includeLastDataDate>
  <offset>0</offset>
  <limit>25</limit>
</jobReportCriteria>

状态
2014-02-06T00:00:00
2014-05-06T00:00:00
[全国]:“全国”
符合事实的
符合事实的
符合事实的
0
25
奇怪的行为

如果我更改了元素的顺序,那么偏移量和限制将被填充。下面是正确序列化的请求

<jobReportCriteria>
  <offset>0</offset>
  <limit>25</limit>
  <groupBy>State</groupBy>
  <timePeriod>
    <from>2014-02-06T00:00:00</from>
    <to>2014-05-06T00:00:00</to>
  </timePeriod>
  <queryString>[nationwide]: &quot; nationwide &quot;</queryString>
  <includeTotalClassifiedPostings>true</includeTotalClassifiedPostings>
  <includeTotalUnclassifiedPostings>true</includeTotalUnclassifiedPostings>
  <includeLastDataDate>true</includeLastDataDate>
</jobReportCriteria>

0
25
状态
2014-02-06T00:00:00
2014-05-06T00:00:00
[全国]:“全国”
符合事实的
符合事实的
符合事实的
将偏移量和限制放在起始位置以某种方式启用序列化。问题是我不能要求客户按照特定的顺序提出请求

有人能告诉我这里到底发生了什么吗

更新:

通过进一步分析,我知道数据成员的顺序会影响序列化,但我仍然认为我已经对成员进行了相应的排序,并为偏移量和限制值指定了最大顺序,以便它始终低于其他参数。但它仍然是空的

此处列出了需要遇到的元素的顺序:

数据排序的基本规则包括:

  • 如果数据协定类型是继承层次结构的一部分,则其基本类型的数据成员始终位于顺序的第一位。

  • 下一个顺序是当前类型的数据成员,它们没有DataMemberAttribute属性集的order属性,按字母顺序排列

  • 接下来是具有DataMemberAttribute属性集的Order属性的任何数据成员。它们首先按Order属性的值排序,如果某个Order值有多个成员,则按字母顺序排序。可以跳过订单值

通过调用CompareOrdinal方法建立字母顺序

即,基类数据成员(即
标准
偏移量
限制
)必须出现在派生类数据成员之前

因此,这里有一些可能绕过这条规则:

  • 修改类设计并展平类层次结构。显然这并不理想,但可以通过将类层次结构替换为由平面类实现的接口层次结构来实现

  • 使用将派生类转换为平面代理代理以进行序列化

  • 联系您的客户并获取他们的信息。这将指定字段的顺序,并允许创建c#类

  • 考虑一下。文件


  • 请显示用于序列化的代码。@johnsa因为反序列化是由MVC完成的,所以我没有执行反序列化的显式代码