一尘不染

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

json

我向我的某些对象添加了自定义属性,如下所示:

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

阅读 421

收藏
2020-07-27

共1个答案

一尘不染

这是专门用于Web API的解决方案,我也在使用:RootFormatter.cs

我基于为ASP.NET Web API创建JSONP格式器编写了它。

我没有使用自定义属性,而是重用了“标题”字段JsonObjectAttribute。这是一个用法代码:

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"
}}
2020-07-27