Как не вернуть NULL, если поле данных не задано в контракте данных - PullRequest
18 голосов
/ 16 апреля 2011

У меня странная проблема с моим WCF сервисом, который возвращает данные в формате JSON. Я хочу вернуть информацию о «Клиенте» на основании запроса, отправленного клиентом.

Клиент может запросить, какие поля информации о клиенте ему нужны, а сервис должен отправить только эту информацию о клиенте.

Например: если клиент запрашивает список клиентов и говорит, что им нужно имя, фамилия, город затем каждому клиенту сервер должен отправить json-ответ с каждым именем поля и соответствующим значением

Что-то вроде ...

[
  {"firstname":"john","lastname":"Goodman","city" :"NY"},
  {"firstname":"brad","lastname":"newman","city" :"LA"}
]

если клиент запрашивает список клиентов только с полями ID и города, тогда ответ должен выглядеть следующим образом

[
  {"id" :"1234","city" :"NY"},
  {"id":"1235","city" :"LA"}
]

Моим первоначальным замыслом было реализовать класс «Клиент», а затем иметь каждое возможное «поле» как поле этого класса. Затем внутри моего сервисного метода я получал список полей, указанных клиентом, и создавал экземпляры объектов customer с установленными только этими свойствами.

Мой рабочий контракт выглядит следующим образом

[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, UriTemplate = "Customers?fields={value}")]
List<Customer> GetCustomers(string value);

Но проблема в том, что когда я декорирую класс с помощью «DataContract», а каждое поле - как «DataMember» .... если некоторые свойства не заданы, они все равно десериализуются как NULL при отправке клиенту. Я не хочу, чтобы это произошло.

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

Затем я подумал о том, чтобы моя Операция вернула IDictionary<string,object>, а затем итеративно добавил каждое поле и значение в эту коллекцию. Это не сработало, потому что, когда словарь сериализован, он показывает {"Key:dfas", "Value:34"} и т. Д. И т. Д., А не то, что я хочу

Так что я застрял. Какой лучший способ решить эту проблему?

Могу ли я пометить свои [DataContract] таким образом, чтобы, если свойства [DataMember] не были установлены, т.е. иметь значение null, их вообще не следовало бы сериализовать и отправлять клиенту?

1 Ответ

47 голосов
/ 16 апреля 2011

Вы можете пометить каждый элемент данных, чтобы он не был сериализован, если он нулевой. Необходимая часть: EmitDefaultValue = false

[DataContract]
public class Person
{
    [DataMember(EmitDefaultValue = false)]
    public string id { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public string firstname { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public string lastname { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public string city { get; set; }
}
...