• システム開発に関わる内容をざっくりと書いていく

ASP.NET Core モデルバインディング失敗(400)の見方

アクションに入る前に 400 になる典型がモデルバインディング/バリデーション失敗。[ApiController] だと自動で ProblemDetails っぽい応答になりやすい。

先に結論

  • まず応答ボディの errors / ModelState 相当を読む
  • JSON のプロパティ名・型・必須・Content-Type を疑う
  • [FromBody] / [FromQuery] / [FromRoute] の取り違えが多い
  • アクションに到達していないなら、バインディング段階の失敗

切り分け手順

  1. ステータスが 400 か、本文にフィールド名が出ているかを確認
  2. リクエストの Content-Type(application/json 等)と生ボディ
  3. DTO のプロパティ名(camelCase / PascalCase)と JSON キー
  4. 数値・日付・enum・null 非許容の型不一致
  5. [Required] / data annotations / FluentValidation の失敗か

よくある原因

  • ボディ無しで [FromBody] 必須パラメータ
  • クエリ想定なのに JSON だけ送っている(またはその逆)
  • ネストオブジェクトや配列の形が合っていない
  • レコード型のコンストラクタ引数名と JSON の不一致

デバッグの型

if (!ModelState.IsValid)
{
    // どのキーが失敗したかをログ
    foreach (var kv in ModelState)
        foreach (var err in kv.Value.Errors)
            _log.LogWarning("{Key}: {Msg}", kv.Key, err.ErrorMessage);
}

関連: ProblemDetails でエラー形式を揃える記事とセットで見るとよい。

ざっくりまとめ

  • 400 の本文(errors)が第一情報
  • FromXxx・型・名前・Content-Type を揃える
  • 到達前失敗か、到達後の手動検証かを分ける

関連記事