我向我的某些对象添加了自定义属性,如下所示:
[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格式器编写了它。
我没有使用自定义属性,而是重用了“标题”字段JsonObjectAttribute。这是一个用法代码:
JsonObjectAttribute
using Newtonsoft.Json [JsonObject(Title = "user")] public class User { public string mail { get; set; } }
然后,将RootFormatter添加到您的App_Start中,并在中进行如下注册WebApiConfig:
WebApiConfig
GlobalConfiguration.Configuration.Formatters.Insert(0, new RootFormatter());
我能够得到类似于WCF的包装响应WebMessageBodyStyle.Wrapped:
WebMessageBodyStyle.Wrapped
{"user":{ "mail": "foo@example.com" }}