Json – how to not return null when a Data member field is not set in the data contract

datacontractserializerjsonserializationwcf

I'm having a strange problem with my WCF service that returns data in JSON format.
I want to return information about a "Customer" based on the request sent by client.

Client can request what fields of information about a customer they need and the service needs to send only that information about the customer.

For Example: If client asks for a list of customers and says they want firstname, lastname, city
of each customer then server should send a json response with each field name and corresponding value

Something like…

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

if client asks for list of customers with ID and city fields only then the response should look like this

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

My initial design was to implement a "Customer" class and then have each possible "field"
as a field of this class. Then inside my service method, I was getting the list of fields specified by the client and instantiating customer objects with only those properties set.

My operation contract looks like this

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

But the problem is when I decorate the class with "DataContract" and each Field as "DataMember"….if some properties are not set, they still get deserialized as NULL when sent to client. I dont want this to happen.

Also, the list of possible fields a customer is very long and so the class became very large. I would rather store these fields as an enum collection in my service rather than fields of a class.

I then thought of having my Operation return a IDictionary<string,object> and then add each field and value iteratively to this collection. That didn't work because, when a dictionary is serialized it shows {"Key:dfas", "Value:34"} etc etc. not what i want

So I'm kinda stuck. What's the best way to solve this problem?

Can I mark my [DataContract] such a way that if [DataMember] properties are not set i.e, null then they shouldn't be serialized and send to client at all?

Best Answer

You can mark each data member so it won't be serialized if it's null. The essential part is: 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; }
}
Related Topic