Espo Espo - 1 year ago 231
JSON Question

How can I add a custom root node when serializing an object with JSON.NET?

I have added a custom property to some of my objects like this:

public class StatusDTO
public int StatusId { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }

The attribute is very simple:

public class JsonCustomRoot :Attribute
public string rootName { get; set; }

public JsonCustomRoot(string rootName)
this.rootName = rootName;

The default output from JSON.NET when serializing an instance of an object is this:


Now the question is: How can I add a root-node to the JSON with the value of the custom attribute like so:


I have found several articles mentioning the IContractResolver interface, but I cannot grasp how to do it. My attempts include this unfinished piece of code:

protected override JsonObjectContract CreateObjectContract(Type objectType)
JsonObjectContract contract = base.CreateObjectContract(objectType);

var info = objectType.GetCustomAttributes()
.SingleOrDefault(t => (Type)t.TypeId==typeof(JsonCustomRoot));
if (info != null)
var myAttribute = (JsonCustomRoot)info;
// How can i add myAttribute.rootName to the root from here?
// Maybe some other method should be overrided instead?

return contract;

Answer Source

Here's a solution specifically for Web API, which I am also using: RootFormatter.cs

I wrote it based on Creating a JSONP Formatter for ASP.NET Web API.

Instead of using a custom attribute I am reusing Title field of JsonObjectAttribute. Here's a usage code:

using Newtonsoft.Json

[JsonObject(Title = "user")]
public class User
    public string mail { get; set; }

Then, add RootFormatter to your App_Start and register it as follows in WebApiConfig:

GlobalConfiguration.Configuration.Formatters.Insert(0, new RootFormatter());

I was able to get a wrapped response similar to WCF's WebMessageBodyStyle.Wrapped:

  "mail": ""
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download