在使用JSON.NET序列化对象时,如何添加自定义根节点?

我已经为我的一些对象添加了一个自定义属性,如下所示:

[JsonCustomRoot("status")] public class StatusDTO { public int StatusId { get; set; } public string Name { get; set; } public DateTime Created { get; set; } } 

属性非常简单:

 public class JsonCustomRoot :Attribute { public string rootName { get; set; } public JsonCustomRoot(string rootName) { this.rootName = rootName; } } 

序列化对象实例时JSON.NET的默认输出是:

 {"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"} 

现在的问题是: 如何使用自定义属性的值向JSON添加根节点,如下所示

 {status:{"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"}} 

我发现有几篇文章提到了IContractResolver接口,但我无法理解如何做到这一点。 我的尝试包括这段未完成的代码:

 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; } 

这是一个专门针对Web API的解决方案,我也在使用它: RootFormatter.cs

我是基于为ASP.NET Web API创建JSONP Formatter而编写的。

我没有使用自定义属性,而是重用JsonObjectAttribute Title字段。 这是一个使用代码:

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

然后,将RootFormatter添加到App_Start并在WebApiConfig按如下方式注册:

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

我能够获得类似于WCF的WebMessageBodyStyle.Wrapped的包装响应:

 {"user":{ "mail": "foo@example.com" }} 

如果您使用匿名对象怎么办?

 JSON.Serialize(new { status = targetObject}); 

一种非常简单的方法是将对象放在另一个对象中。 它可能是一个过于简单的看待它,但这适用于处理集合和单个对象。

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

现在,如果您将StatusDTO放在statusJsonModel对象中并将其序列化为Json。 它应该给你你想要的答案。

我的一个项目中遇到了类似的挑战。 以下是我解决问题的步骤。

1.我的实体课程

 public class Product { [Key] public string Id { get; set; } public string Title { get; set; } public string Album { get; set; } public string Artist { get; set; } public string Genre { get; set; } } 

2.创建另一个类,以此forms定义。

  public class KindOfMedia { public KindOfMedia() { Product = new List(); } public List Product { get; set; } } 

3. Web API控制器,它将返回json

  public HttpResponseMessage Products() { var kind = new KindOfMedia(); kind.Products = new List(); kind.Products.Add(new Product { Id = Guid.NewGuid().ToString(), Title = "I am A Winner", Album = "", Artist = "Project Fame", Genre = "Contemporal" }); kind.Products.Add(new Product { Id = Guid.NewGuid().ToString(), Title = "Great Nation", Album = "Oceans", Artist = "Timi Dakolo", Genre = "Gospel" }); return Request.CreateResponse(HttpStatusCode.OK, kind); } 

4.将此行代码添加到App_Start文件夹中的WebApi Config文件中

  var json = config.Formatters.JsonFormatter; json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None; 

请注意, Newtonsoft.Json.PreserveReferencesHandling.None不会保留序列化类型的引用

由此产生的Json是

 { "Musics": [ { "Id": "bf9faeee-7c39-4c33-a0ea-f60333604061", "Title": "I am A Winner", "Album": "", "Artist": "Project Fame", "Genre": "Contemporal" }, { "Id": "243edd32-7ba2-4ac4-8ab9-bba6399cb0a6", "Title": "Great Nation", "Album": "Oceans", "Artist": "Timi Dakolo", "Genre": "Gospel" } ] }