First let's see how we can control, which members are serialized.

As we saw in earlier article how JsonMediaTypeFormatter and XmlMediaTypeFormatter serialize .Net CLR(Common Language Runtime) type. But actually above mentioned formatters use Json.NET library and DataContractSerializer class, respectively, to perform serialization. Below rules get applied while choosing members for serialization:

- Public fields and properties are serialized with both Json.NET and DataContractSerializer.

- Read-only properties are serialized by Json.NET but not by DataContractSerializer. By saying read-only, property with only get, no set.

- Private, protected and internal members are not serialized in either case.

There may be a situation, where you need to prevent serialization for one or multiple members. To accomplish this we have few attributes, which can be applied to those members:

- IgnoreDataMember: Prevent serialization for Json.NET and DataContractSerializer.

- JsonIgnore: Prevent serialization for Json.NET

Note: IgnoreDataMember attribute is located under System.Runtime.Serialization assembly.

Example:

using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;

public class Team
{
    public int Id { get; set; }

    public string TeamName { get; set; }

    // Serialized with json.NET
    public DateTime CreatedOn
    {
        get
        {
            return DateTime.Now;
        }
    }

    // Ignored by Json.NET
    [JsonIgnore]
    public string TeamSummary { get; set; }
    
    // Ignored by both Json.NET and DataContractSerializer
    [IgnoreDataMember]
    public string TeamOwner { get; set; }
}


Above we saw how we can prevent members from getting serialized. But, suppose in a situation we need to allow/ choose members for serialization.

Let's see how can we do that:

Apply DataContract attribute on the class and apply DataMember attribute to those members that we want to get serialized.

This approach works with both Json.NET and DataContractSerializer.

Example:

using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;

[DataContract]
public class Team
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string TeamName { get; set; }

    // Serialized with json.NET but fails with an exception in case
    // of DataContractSerializer
    [DataMember]
    public DateTime CreatedOn
    {
        get
        {
            return DateTime.Now;
        }
    }

    // Not get serialized
    public string TeamSummary { get; set; }
 
    [DataMember]
    public string TeamOwner { get; set; }
} 


Fine. Till now we saw how we can choose which members to allow for serialization.

Now let's control how members are getting serialized.

ASP.NET Web API uses Json.NET and DataContractSerializer for serializing CLR objects. But for XML, we can also use XMLSerializer instead.

To use XMLSerializer we will need to take couple of steps:

First is to add below line of code in WebApiConfig file:

config.Formatters.XmlFormatter.UseXmlSerializer = true;

But, why we need to use XMLSerializer?

As XMLSerializer gives us more control over the resulting XML format. And it will be needed if we need to generate the serialized XML in a predefined/ existing format.

But while choosing between DataContractSerializer and XMLSerializer, we should be aware of the fact that DataContractSerializer is comparatively faster and can handle more types.

How can we control member names in serialization output?

Now let's see how can we control member names, getting serialized in JSON / XML format.

By default, member names are used as it is in serialization and same member name appears in serialized representation. But, we can change the member name in serialized output by applying some attributes with parameters.

- For Json.NET, we use JsonProperty attribute with a PropertyName.

- For DataContractSerializer, DataMember can be used with Name. But, in case of DataContact serializer we will need to apply DataContract on class, else it will have no effect.

public class Team
{
    [JsonProperty(PropertyName="Identifier")]
    public int Id { get; set; }

    [JsonProperty(PropertyName="TeamTitle")]
    public string TeamName { get; set; }

    // No effect unless DataContract used on class
    [DataMember(Name="Owner")]    
    public string TeamOwner { get; set; }
}


Let's see how we can return dynamic object/ list or in other words, return only some members of a class:

Suppose we have a class like below:

public class Team
{
    public int Id { get; set; }

    public string TeamName { get; set; }

    public string TeamOwner { get; set; }
}

But, we do not want to return TeamOwner to the client, consuming our web api. Let's see below method which is doing this:

public HttpResponseMessage Get()
{
    var teams = _teamList.Select(t => new
        {
            Identifier = t.Id,
            Name = t.TeamName
        });
    var response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new ObjectContent(teams.GetType(), teams,  Configuration.Formatters.JsonFormatter)
         };
    return response;
}


Above we can see, how we are selecting only Id and TeamName and assigning to Identifier and Name respectively; It will create list of objects, which will contain only two members, Identifier and Name.

Summary

In above details we saw:

How can we control which members are getting serialized.

Controlling, how members are getting serialized.

Controlling returned members dynamically.


Stay tuned, if looks interesting.

Reference:
Book: Practical ASP.NET Web API [Apress]

Previous > ASP.NET WEB API Part 5 - HTTP Response format (MediaTypeFormatter)

Next > ASP.NET WEB API Part 7 - Customizing Web API response

Discussion
10 X 3 =
** To prevent abusing comments from publishing, posted comments will be reviewed and then published!
 Mritunjay Kumar