ASP.NET MVCコントローラーメソッドからJSON.NETによってシリアル化されたキャメルケースJSONを返すにはどうすればよいですか?


246

私の問題は、JSON.NET によってシリアル化されたASP.NET MVCコントローラーメソッドからのActionResultを介して(標準のPascalCaseではなく)camelCased JSONデータを返したいということです

例として、次のC#クラスを考えます。

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

デフォルトでは、このクラスのインスタンスをMVCコントローラーからJSONとして返す場合、次の方法でシリアル化されます。

{
  "FirstName": "Joe",
  "LastName": "Public"
}

私はそれを(JSON.NETによって)シリアル化したいと思います:

{
  "firstName": "Joe",
  "lastName": "Public"
}

どうすればよいですか?

回答:


389

または、単に次のように記述します。

JsonConvert.SerializeObject(
    <YOUR OBJECT>, 
    new JsonSerializerSettings 
    { 
        ContractResolver = new CamelCasePropertyNamesContractResolver() 
    });

例えば:

return new ContentResult
{
    ContentType = "application/json",
    Content = JsonConvert.SerializeObject(new { content = result, rows = dto }, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }),
    ContentEncoding = Encoding.UTF8
};

2
ただし、コントローラーメソッドごとにContentResultを構成する必要があるため、これは使用がより複雑です。
aknuds1 2014年

2
ええ、私はあなたの答えが再利用可能なソリューションであったことを理解しています。私のポイントは、それがSerializeメソッドのパラメーターにすぎないことをより明確にすることです。
WebDever 2014年

1
ControllerメソッドからJSONを返す場合は、おそらくを使用する必要がありますApiController。その場合、この答えはうまくいきます。
Simon Hartcher、2015年

1
@SimonHartcherただし、一般的なケースではなく、質問の範囲を検討してください。
aknuds1 2015年

1
JSONの有効なコンテンツタイプはapplication/json、ではなくtext/plainです。
Fred

94

Mats Karlssonのブログでこの問題の優れた解決策を見つけました。解決策は、JSON.NETを介してデータをシリアル化するActionResultのサブクラスを記述し、キャメルケースの規則に従うように後者を構成することです。

public class JsonCamelCaseResult : ActionResult
{
    public JsonCamelCaseResult(object data, JsonRequestBehavior jsonRequestBehavior)
    {
        Data = data;
        JsonRequestBehavior = jsonRequestBehavior;
    }

    public Encoding ContentEncoding { get; set; }

    public string ContentType { get; set; }

    public object Data { get; set; }

    public JsonRequestBehavior JsonRequestBehavior { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        var response = context.HttpContext.Response;

        response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data == null)
            return;

        var jsonSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
        response.Write(JsonConvert.SerializeObject(Data, jsonSerializerSettings));
    }
}

次に、このクラスをMVCコントローラーメソッドで次のように使用します。

public ActionResult GetPerson()
{
    return new JsonCamelCaseResult(new Person { FirstName = "Joe", LastName = "Public" }, JsonRequestBehavior.AllowGet)};
}

3
完璧な答え:クリーンで再利用可能!ありがとうございました。
サンダー2015年

1
このソリューションはまだ機能していますが。しかし、それは4年前に提案されました。より良い解決策はありますか?
SharpCoder 2017年

59

WebAPIについては、次のリンクを確認してください。http//odetocode.com/blogs/scott/archive/2013/03/25/asp-net-webapi-tip-3-camelcasing-json.aspx

基本的には、このコードを次のコードに追加しますApplication_Start

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();

4
Web APIとMVCがASP.NET 6に統合されました
AlexFoxGill 2015

1
利便性のためのリンク。この設定は、この回答で本当にうまく機能します:stackoverflow.com/a/26068063/398630(別の質問ですが、一緒に使用します。このリンクにより、私や他の人が将来グーグルするのを防ぐことができます)。
BrainSlugs83

37

これはあなたが探している簡単な答えだと思います。これは、からだショーンWildermuthさんのブログ:

// Add MVC services to the services container.
services.AddMvc()
  .AddJsonOptions(opts =>
  {
    opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
  });

2
皆さん、お詫びします。私はこの投稿を読みすぎました。ASP.NET 5用です
。– Quantium

8
皮肉なことに、私はあなたがここで答えた質問への答えを探してここに来たので、それはOPの質問への答えではありませんでしたが、とにかく私を助けました。ありがとう!:)
porcus

1
@porcusが言ったことの2番目です。@Quantiumに感謝!
Gromer 2016年

4
FYI ASP.NETコア1.0デフォルトOOTBによってそれのキャメルケースの場合
クリスMarisic

3
結局のところ、これは(正確には).NET Core 1.0のデフォルトではないことがわかります。このソリューションは動的プロパティに影響し、デフォルトでは影響を受けません。stackoverflow.com/questions/41329279/...
ニールスBrinch

13

カスタムフィルターの代わりに、オブジェクトをJSONにシリアル化する拡張メソッドを作成することもできます。

public static class ObjectExtensions
{
    /// <summary>Serializes the object to a JSON string.</summary>
    /// <returns>A JSON string representation of the object.</returns>
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new StringEnumConverter() }
        };

        return JsonConvert.SerializeObject(value, settings);
    }
}

次に、コントローラーアクションから戻るときにそれを呼び出します。

return Content(person.ToJson(), "application/json");

エレガントでシンプル。
マルカウ2018

1
静的な読み取り専用フィールドに設定を転送し、FromJson補完メソッドを追加することもできます。
路地の蒸気

8

シンプルなほうがIMOが優れています!

なぜこれをしませんか?

public class CourseController : JsonController
{
    public ActionResult ManageCoursesModel()
    {
        return JsonContent(<somedata>);
    }
}

単純な基本クラスコントローラー

public class JsonController : BaseController
{
    protected ContentResult JsonContent(Object data)
    {
        return new ContentResult
        {
            ContentType = "application/json",
             Content = JsonConvert.SerializeObject(data, new JsonSerializerSettings { 
              ContractResolver = new CamelCasePropertyNamesContractResolver() }),
            ContentEncoding = Encoding.UTF8
        };
    }
}

7

ASP.NET Core MVC。

    public IActionResult Foo()
    {
        var data = GetData();

        var settings = new JsonSerializerSettings 
        { 
            ContractResolver = new CamelCasePropertyNamesContractResolver() 
        });

        return Json(data, settings);
    }

さらに、Startup.csファイルに追加します。
FatAlbert

6

以下は、オブジェクトの配列をシリアル化することによってjson文字列(cameCase)を返すアクションメソッドです。

public string GetSerializedCourseVms()
    {
        var courses = new[]
        {
            new CourseVm{Number = "CREA101", Name = "Care of Magical Creatures", Instructor ="Rubeus Hagrid"},
            new CourseVm{Number = "DARK502", Name = "Defence against dark arts", Instructor ="Severus Snape"},
            new CourseVm{Number = "TRAN201", Name = "Transfiguration", Instructor ="Minerva McGonal"}
        };
        var camelCaseFormatter = new JsonSerializerSettings();
        camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
        return JsonConvert.SerializeObject(courses, camelCaseFormatter);
    }

2番目のパラメーターとして渡されたJsonSerializerSettingsインスタンスに注意してください。それがcamelCaseを実現させるものです。


4

私はこれが好きでした:

public static class JsonExtension
{
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize
        };
        return JsonConvert.SerializeObject(value, settings);
    }
}

これはMVCコアの単純な拡張メソッドであり、プロジェクトのすべてのオブジェクトにToJson()機能を提供します。MVCプロジェクトの私の意見では、ほとんどのオブジェクトはjsonになることができるはずですが、もちろんそれは依存します:)


ToJsonメソッドが呼び出されるたびに新しい変数を初期化しないように、「設定」変数をメソッドの外に(プライベート静的フィールド「camelCaseSettings」として)抽出することを検討してください。
エクス

4

「Startup.cs」ファイルで設定を行う必要があります

また、JsonConvertのデフォルト値で定義する必要があります。これは、後でライブラリを直接使用してオブジェクトをシリアル化する場合です。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => {
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }

この回答はASP.NET Coreには当てはまりますが、ASP.NET(問題のフレームワーク)には当てはまりません。
Nate Barbettini、

0

.netコアWeb APIまたはIHttpAction結果でActionResultを返す場合は、モデルをOk()メソッドでラップして、フロントエンドの大文字と小文字を一致させ、シリアル化することができます。JsonConvertを使用する必要はありません。:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.