web-dev-qa-db-ja.com

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

ここでの質問は次のとおりです:soのようなカスタム属性の値を使用して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;
}
14
Espo

これは私が使用しているWebAPI専用のソリューションです: RootFormatter.cs

ASP.NET Web API用のJSONPフォーマッターの作成 に基づいて作成しました。

カスタム属性を使用する代わりに、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": "[email protected]"
}}
5
Eugene Yokota

匿名オブジェクトを使用する場合はどうなりますか?

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

これにアプローチする非常に簡単な方法は、オブジェクトを別のオブジェクトの中に配置することです。それを見るのは単純すぎるかもしれませんが、これはコレクションや単一のオブジェクトを操作するときに機能します。

  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としてシリアル化するとします。それはあなたにあなたの望む答えを与えるはずです。

4
Benjishk