言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

  1. トップページ
  2. ASP.NET辞典
  3. [HttpPost]

[HttpPost]

対応: ASP.NET Core 6(2021)

『ASP.NET Core』の [HttpPost] は、コントローラーのアクションメソッドが HTTP POST リクエストを処理することを示す属性です。この属性を付けたメソッドは、フォームの送信・新規リソースの作成・ログイン処理など、クライアントからサーバーにデータを送信する操作に応答します。

構文

// ルートテンプレートを指定しない場合はコントローラーのルートにマッピングされます
[HttpPost]
public アクション名()
{
    // POSTリクエストを処理する実装をここに書きます
}

// ルートテンプレートを指定することで追加のパスセグメントを設定できます
[HttpPost("テンプレート")]
public アクション名()
{
    // テンプレートにマッチしたPOSTリクエストを処理します
}

// リクエストボディをモデルとして受け取る場合は [FromBody] を付けます
[HttpPost]
public アクション名([FromBody] モデル型 モデル名)
{
    // JSONなどで送信されたボディが自動的にモデルにバインドされます
}

リクエストデータの受け取り方

記述例概要
[FromBody]リクエストボディ(JSON・XMLなど)をモデルにバインドします。[ApiController] が付いている場合は省略しても自動推論されます。
[FromForm]HTMLフォーム(application/x-www-form-urlencoded または multipart/form-data)で送信されたデータをモデルにバインドします。
[FromRoute]URLのパスセグメントをパラメーターとして受け取ります。ルートテンプレートの {パラメーター名} と対応します。
[FromQuery]URLのクエリパラメーター(?key=value)をバインドします。POSTでも使用できます。
[FromHeader]HTTPリクエストヘッダーの値をパラメーターとして受け取ります。

サンプルコード

[HttpPost] 属性を使って新規商品の登録・バリデーションエラー処理・作成結果の返却を行うコントローラーを定義する例です。

// ProductsController.cs
// 商品情報を管理するWeb APIコントローラーを定義します

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    // サンプル用の商品データを保持するリストです(本来はDBを使います)
    private static readonly List<Product> _products = new List<Product>
    {
        new Product { Id = 1, Name = "りんご",   Price = 150, Category = "果物" },
        new Product { Id = 2, Name = "みかん",   Price = 100, Category = "果物" },
    };

    // 次に割り当てるIDを管理する変数です
    private static int _nextId = 3;

    // POST api/products
    // リクエストボディに含まれる商品データを受け取って登録します
    [HttpPost]
    public ActionResult<Product> Create([FromBody] ProductCreateRequest request)
    {
        // [ApiController] が付いているためモデルバリデーションは自動実行されます
        // バリデーションエラーがある場合はここに到達する前に 400 Bad Request が返ります

        // 新しい商品オブジェクトを作成します
        var newProduct = new Product
        {
            Id       = _nextId++,
            Name     = request.Name,
            Price    = request.Price,
            Category = request.Category,
        };

        // 商品リストに追加します
        _products.Add(newProduct);

        // 201 Created とともに作成したリソースのURLと内容を返します
        // nameof(GetById) は GET api/products/{id} のルート名を参照します
        return CreatedAtAction(nameof(GetById), new { id = newProduct.Id }, newProduct);
    }

    // GET api/products/{id}
    // 作成後の 201 レスポンスに含める Location ヘッダーのために定義します
    [HttpGet("{id:int}")]
    public ActionResult<Product> GetById(int id)
    {
        var product = _products.Find(p => p.Id == id);

        if (product == null)
        {
            // 商品が見つからない場合は 404 Not Found を返します
            return NotFound();
        }

        return Ok(product);
    }
}

// 商品データを表すモデルクラスです
public class Product
{
    public int    Id       { get; set; }
    public string Name     { get; set; }
    public int    Price    { get; set; }
    public string Category { get; set; }
}

// POST リクエストボディ用のDTOクラスです
// DataAnnotations でバリデーションルールを定義します
public class ProductCreateRequest
{
    // 商品名は必須で、1文字以上50文字以内とします
    [Required(ErrorMessage = "商品名は必須です。")]
    [StringLength(50, MinimumLength = 1, ErrorMessage = "商品名は1文字以上50文字以内で入力してください。")]
    public string Name { get; set; }

    // 価格は1以上の整数とします
    [Range(1, int.MaxValue, ErrorMessage = "価格は1以上の値を入力してください。")]
    public int Price { get; set; }

    // カテゴリーは必須とします
    [Required(ErrorMessage = "カテゴリーは必須です。")]
    public string Category { get; set; }
}

各リクエストの例と期待されるレスポンスです。

// 正常な登録リクエスト
// POST api/products
// Content-Type: application/json
// { "name": "ぶどう", "price": 300, "category": "果物" }
// → 201 Created
//   Location: /api/products/3
//   { "id": 3, "name": "ぶどう", "price": 300, "category": "果物" }

// バリデーションエラーのリクエスト(名前が空)
// POST api/products
// { "name": "", "price": 300, "category": "果物" }
// → 400 Bad Request
//   { "errors": { "Name": ["商品名は必須です。"] } }

// バリデーションエラーのリクエスト(価格が0以下)
// POST api/products
// { "name": "なし", "price": 0, "category": "果物" }
// → 400 Bad Request
//   { "errors": { "Price": ["価格は1以上の値を入力してください。"] } }

概要

[HttpPost] 属性は、HTTP の POST メソッドとアクションメソッドを結び付けるルーティング属性です。POST はサーバー上に新しいリソースを作成したり、データを送信して処理を実行させるために使われます。GET と異なり、リクエストボディにデータを含めることができるため、フォームの送信・JSONデータの送信・ファイルのアップロードなど幅広い用途で利用されます。

新規リソースを作成するアクションでは、成功時に 201 Created を返すのが REST の慣例です。CreatedAtAction() または CreatedAtRoute() を使うと、レスポンスの Location ヘッダーに作成されたリソースのURLを自動で含めることができます。[ApiController] を使用している場合は、ModelState のバリデーションエラーが自動的に 400 Bad Request として返されるため、アクションメソッド内で ModelState.IsValid を手動チェックする必要がありません。リソースの更新・削除については [HttpPut][HttpPatch][HttpDelete] など他の HTTP メソッド属性もあわせてご参照ください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。