2014-11-20 2 views
0

У нас есть веб-API, который использует базовый класс для всех моделей. Ниже представлена ​​структураXml Сериализация не работает должным образом в ASP.NET 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(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. Все работает нормально. Я получаю значения для смещения и ограничения в абстрактном классе. Но при использовании сериализации XML смещение и предел не заполняются.

Ниже запрос я передаю к API с помощью Client Rest

<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> 

Странного поведения

Если я изменил порядок элементов, то офсетные и ограничения становятся заселенными. ниже запрос, который правильно сериализуется.

<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> 

Смещение и ограничение при запуске как-то разрешает сериализацию. Проблема в том, что я не могу попросить клиента оформить запрос в определенном порядке.

Может кто-нибудь сообщить мне, что именно происходит здесь?

Update:

При дальнейшем анализе я узнал, что порядок элементов данных влияют на сериализацию, но все же я думаю, что я приказал моим членам соответствующим образом и с учетом смещения и предельных значений максимального порядка, так что он всегда приходит ниже других параметров. но все-таки речь идет о утратившим

+0

Просьба указать код, который вы используете для сериализации. –

+0

@JohnSaunders Де-сериализация выполняется MVC, у меня нет явного кода для выполнения десериализации – Umamaheswaran

ответ

0

Порядок, в котором DataContractSerializer требует элементов, которые могут возникнуть разъяснено здесь: Data Member Order:

Основные правила для упорядочения данных включают в себя:

  • Если тип контракта данных является частью иерархии наследования, члены данных его базовых типов всегда являются первыми в порядке.

  • Следующие в порядке являются членами данных текущего типа, которые не имеют свойства Order атрибута DataMemberAttribute, в алфавитном порядке.

  • Далее перечислены все члены данных, у которых есть свойство Order атрибута атрибута DataMemberAttribute. Они упорядочиваются по значению свойства Order сначала, а затем в алфавитном порядке, если имеется более одного члена определенного значения Order. Значения заказа могут быть пропущены.

Алфавитный порядок устанавливается путем вызова метода CompareOrdinal.

т.е. элементы данных базового класса (т.е. offsetlimit и из Criteria) должны появляться перед потребности, полученные элементы данных класса.

Итак, вот некоторые возможности обойти это правило:

  1. Измените дизайн класса и придавить иерархии классов. Очевидно, что это не идеально, но вы можете сделать это, заменив иерархию классов иерархией интерфейса, реализованной с помощью плоских классов.

  2. Используйте код data contract surrogate, чтобы преобразовать производный класс в суррогат с прокси-сервером для сериализации.

  3. Свяжитесь с вашим клиентом и получите их servicemodel metadata. Это укажет порядок полей и позволит классам C# быть automatically generated.

  4. Рассмотрите switching to XMLSerializer. Документация here.

Смежные вопросы