a 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()
サービスが含まれていることを確認することから始めます。ConfigureServices
Startup.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-Type
とAccept
リクエストのContent-Type
およびAccept
ヘッダーが正しく設定されていることを確認する必要があります。あなたのケース(JSON)では、に設定する必要があります。application/json
WebAPIがデフォルトでJSONとして応答するようにしたい場合は、要求ヘッダーが何を指定しているかに関係なく、いくつかの方法で行うことができます。
方法1
先に推奨した記事(応答データのフォーマット)で示したように、コントローラー/アクションレベルで特定のフォーマットを強制できます。私は個人的にはこのアプローチが好きではありません...しかし、ここでは完全性のためです:
特定の形式を強制する特定のアクションの応答形式を制限したい場合は、[Produces]フィルターを適用できます。[Produces]フィルターは、特定のアクション(またはコントローラー)の応答形式を指定します。ほとんどのフィルターと同様に、これはアクション、コントローラー、またはグローバルスコープで適用できます。
[Produces("application/json")]
public class AuthorsController
[Produces]
フィルタ内のすべてのアクションを強制的に
AuthorsController
他のフォーマッタは、アプリケーションのために構成され、クライアントは、提供された場合であっても、JSON形式の応答を返すようにAccept
異なる、利用可能なフォーマットを要求ヘッダー。
方法2
私が推奨する方法は、WebAPIが要求されたフォーマットですべての要求に応答することです。ただし、要求された形式を受け入れない場合は、デフォルト(JSONなど)にフォールバックします。
最初に、それをオプションに登録する必要があります(前述のように、デフォルトの動作をやり直す必要があります)。
options.RespectBrowserAcceptHeader = true; // false by default
最後に、サービスビルダーで定義されたフォーマッターのリストを並べ替えるだけで、Webホストはデフォルトでリストの一番上(つまり、位置0)に配置するフォーマッターになります。
詳細については、この.NET Web開発とツールのブログエントリをご覧ください。
CreatedAtRoute
等の方法を