ASP.NET Core はステータスコード付きの JSON を返します 質問する

ASP.NET Core はステータスコード付きの JSON を返します 質問する

.NET Core Web API コントローラーで HTTP ステータス コードを含む JSON を返す正しい方法を探しています。私は次のように使用していました:

public IHttpActionResult GetResourceData()
{
    return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}

これは 4.6 MVC アプリケーションでは発生していましたが、現在 .NET Core では発生していないようですIHttpActionResultActionResult次のように使用しています。

public ActionResult IsAuthenticated()
{
    return Ok(Json("123"));
}

しかし、サーバーからの応答は、以下の画像のように奇妙です。

ここに画像の説明を入力してください

Web API 2 で行ったように、Web API コントローラーが HTTP ステータス コードを含む JSON を返すようにしたいだけです。

ベストアンサー1

最も基本的なバージョンは、次のようにJsonResultなります。

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

ただし、独自の応答コードを明示的に処理できないため、これは問題の解決には役立ちません。

ステータス結果を制御するには、 を返す必要があります。ActionResultこれにより、その型を活用できるようになりますStatusCodeResult

例えば:

// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
    var result = _authorRepository.GetByNameSubstring(namelike);
    if (!result.Any())
    {
        return NotFound(namelike);
    }
    return Ok(result);
}

上記の両方の例は、Microsoft ドキュメントの「応答データのフォーマット」から取得した優れたガイドから引用したものです。


追加情報

私が頻繁に遭遇する問題は、VS の「新しいプロジェクト」テンプレートのデフォルト構成を使用するのではなく、WebAPI をより細かく制御したいということです。

いくつかの基本事項を理解していることを確認しましょう...

ステップ1: サービスを構成する

ASP.NET Core WebAPI がステータス コードを完全に制御した JSON シリアル化オブジェクトで応答するようにするには、まず、通常 にある メソッドAddMvc()にサービスが含まれていることを確認する必要があります。ConfigureServicesStartup.cs

AddMvc()他のリクエスト タイプへの応答とともに、JSON の入力/出力フォーマッタが自動的に含まれることに注意することが重要です。

プロジェクトで完全な制御が必要であり、WebAPI がさまざまなリクエスト タイプに対してどのように動作するか、application/json他のリクエスト タイプ (標準のブラウザー リクエストなど) には応答しないかなど、サービスを厳密に定義する必要がある場合は、次のコードを使用して手動で定義できます。

public void ConfigureServices(IServiceCollection services)
{
    // Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
    // https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs

    services
        .AddMvcCore(options =>
        {
            options.RequireHttpsPermanent = true; // does not affect api requests
            options.RespectBrowserAcceptHeader = true; // false by default
            //options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();

            //remove these two below, but added so you know where to place them...
            options.OutputFormatters.Add(new YourCustomOutputFormatter()); 
            options.InputFormatters.Add(new YourCustomInputFormatter());
        })
        //.AddApiExplorer()
        //.AddAuthorization()
        .AddFormatterMappings()
        //.AddCacheTagHelper()
        //.AddDataAnnotations()
        //.AddCors()
        .AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}

別のシリアル化形式 (protobuf、thrift など) に対応する必要がある場合に備えて、独自のカスタム入力/出力フォーマッタを追加する方法も用意されていることがわかります。

上記のコードの大部分は、メソッドの複製ですAddMvc()。ただし、テンプレートで事前に提供されているサービスを使用するのではなく、各サービスごとに定義して、各「デフォルト」サービスを独自に実装しています。コード ブロックにリポジトリ リンクを追加しました。または、AddMvc() GitHub リポジトリからチェックアウトすることもできます。

最初から実装しないのではなく、デフォルトを「元に戻す」ことでこの問題を解決しようとするガイドがいくつかあることに注意してください...現在オープンソースで作業していることを考慮すると、これは冗長な作業であり、悪いコードであり、率直に言ってすぐに消える古い習慣です。


ステップ2: コントローラーを作成する

あなたの疑問を解決するために、とても簡単な例を挙げてみます。

public class FooController
{
    [HttpPost]
    public async Task<IActionResult> Create([FromBody] Object item)
    {
        if (item == null) return BadRequest();

        var newItem = new Object(); // create the object to return
        if (newItem != null) return Ok(newItem);

        else return NotFound();
    }
}

ステップ3: 確認しContent-TypeAccept

リクエストContent-Type内のおよびAcceptヘッダーが適切に設定されていることを確認する必要があります。あなたの場合 (JSON) では、 に設定する必要があります。application/json

リクエスト ヘッダーの指定に関係なく、WebAPI がデフォルトで JSON として応答するようにしたい場合は、いくつかの方法でそれを実行できます。

方法 1前に推奨した記事 (応答データのフォーマット) に示されているように、コントローラー/アクション レベルで特定の形式を強制することができます。個人的にはこのアプローチは好きではありませんが、完全性のためにここに示します。

特定の形式の強制特定のアクションの応答形式を制限する場合は、[Produces] フィルターを適用できます。[Produces] フィルターは、特定のアクション (またはコントローラー) の応答形式を指定します。ほとんどのフィルターと同様に、これはアクション、コントローラー、またはグローバル スコープで適用できます。

[Produces("application/json")]
public class AuthorsController

フィルタは、アプリケーションに他のフォーマッタが構成されていて、クライアントが別の利用可能な形式を要求するヘッダーを提供した場合でも、[Produces]内のすべてのアクションに JSON 形式の応答を返すように強制します。AuthorsControllerAccept

方法 2私が推奨する方法は、WebAPI が要求された形式ですべてのリクエストに応答することです。ただし、要求された形式を受け入れない場合は、デフォルト (JSON など) にフォールバックします。

まず、オプションでそれを登録する必要があります(前述のように、デフォルトの動作をやり直す必要があります)

options.RespectBrowserAcceptHeader = true; // false by default

最後に、サービス ビルダーで定義されたフォーマッタのリストを並べ替えるだけで、Web ホストはリストの先頭 (つまり位置 0) に配置したフォーマッタをデフォルトとして選択します。

詳細については、この.NET Web開発およびツールのブログエントリをご覧ください。

おすすめ記事