WCF обернуть переменные сложные типы для REST - PullRequest
0 голосов
/ 01 июля 2010

Я реализую API lo-REST и собираюсь вернуть либо XML, либо JSON. Сборка в .NET WCF.

Мне нравится дизайн API-интерфейсов Flickr и Last FM, которые оборачивают свои переменные сложные типы в простой ответ:

<lfm status="ok">
  <user>
    <name>RJ</name>
    <realname>Richard Jones </realname>
    <country>UK</country>
    <age>27</age>
  </user>
</lfm>

или

<lfm status="ok">
  <track>
    <name>Best track ever</name>
    <album>Thriller</album>
  </user>
</lfm>

или

<lfm status="fail">
  ... error details
</lfm>

Сериализация сложных типов проста, как и следовало ожидать (с использованием DataContract, DataMember и т. Д.). Но завертывание его в какой-то пользовательский ответ сбивает меня с толку из-за переменных типов, которые могут содержаться внутри. Предоставление ответа члену типа object, заполненному сложным типом, не сериализуется:

[DataContract]
public class Response
{
    public enum ResponseStatus
    {
        ok,
        fail
    }

    [DataMember]
    public ResponseStatus Status { get; set; }

    [DataMember]
    public object Data { get; set; }

}

Любые идеи или помощь с благодарностью.

Большое спасибо, Alex

EDIT: Тим Робертс предлагает интересное решение, хотя оно не очень хорошо сериализуется. Можно указать все потенциальные сложные типы в качестве свойств с указанием [DataMember (EmitDefaultValue = false)], чтобы значения null не сериализовались. Не уверен, что это лучшее решение.

1 Ответ

1 голос
/ 01 июля 2010

Вы можете определить иерархию классов для ваших Data типов в Response:

например,

[DataContract]
public abstract class Data
{ }

[DataContract]
public class FooData : Data
{ }

[DataContract]
public class BarData : Data
{ }

, а затем указать известные типы в классе Response:

[DataContract]
[KnownType(typeof(FooData))]
[KnownType(typeof(BarData))]
public class Response
{
    public enum ResponseStatus
    {
        ok,
        fail
    }

    [DataMember]
    public ResponseStatus Status { get; set; }

    [DataMember]
    public Data Data { get; set; }
}
...