Serialization Helper for ASP.NET Web API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net.Http.Formatting; | |
using System.Runtime.Serialization; | |
using Newtonsoft.Json; | |
using WebApiContrib.Formatting; | |
namespace WebApiContrib | |
{ | |
public static class SerializationHelper | |
{ | |
/// <summary> | |
/// Configure serializer for Json formatter to handle cyclical references. | |
/// </summary> | |
/// <param name="jsonFormatter">Json media type formatter</param> | |
public static void ConfigJsonSerializer(this BaseJsonMediaTypeFormatter jsonFormatter) | |
{ | |
jsonFormatter.SerializerSettings.PreserveReferencesHandling = | |
PreserveReferencesHandling.All; | |
} | |
/// <summary> | |
/// Configure serializer for Xml formatter to handle cyclical references. | |
/// </summary> | |
/// <param name="xmlFormatter">Web API Xml Formatter.</param> | |
/// <param name="types">Types returned from controller actions.</param> | |
public static void ConfigXmlSerializer | |
(this XmlMediaTypeFormatter xmlFormatter, params Type[] types) | |
{ | |
foreach (var type in types) | |
{ | |
var serializer = new DataContractSerializer(type, | |
null, int.MaxValue, false, true, null); | |
xmlFormatter.SetSerializer(type, serializer); | |
} | |
} | |
/// <summary> | |
/// Configure ProtoBuf formatter to handle cyclical references. | |
/// </summary> | |
/// <param name="types"></param> | |
public static void ConfigProtoBufFormatter(params Type[] types) | |
{ | |
foreach (var type in types) | |
{ | |
var meta = ProtoBufFormatter.Model.Add(type, false); | |
var props = type.GetProperties(); | |
for (var i = 0; i < props.Length; i++) | |
{ | |
meta.Add(i + 1, props[i].Name); | |
} | |
meta.AsReferenceDefault = true; | |
} | |
} | |
} | |
} |
Here is a sample WebApiConfig class that uses the serialization helper:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Handle cyclical references for xml
config.Formatters.XmlFormatter.ConfigXmlSerializer
(typeof(Category), typeof(List<Product>));
// Handle cyclical references for json
config.Formatters.JsonFormatter.ConfigJsonSerializer();
// Handle cyclical references for bson
var bsonFormatter = new BsonMediaTypeFormatter();
bsonFormatter.ConfigJsonSerializer();
config.Formatters.Add(bsonFormatter);
// Handle cyclical references for protobuf
SerializationHelper.ConfigProtoBufFormatter
(typeof(Category), typeof(Product));
var protoFormatter = new ProtoBufFormatter();
config.Formatters.Add(protoFormatter);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Three serialization helper methods for configuring json, xml and protobuf media type formatters to handle cyclical references. Note that the DataContractSerializer is configured on a per-type basis and requires concrete types returned by Api controller actions, for example, List instead of just T. The ProtoBuf formatter also requires per-type configuration, but configures entity types (T rather than List).
To use them you'll need the following NuGet packages:
Newtonsoft.Json
Microsoft.AspNet.WebApi.Client
WebApiContrib.Formatting.ProtoBuf