ASP.NET Core

【 ASP.NET Core】CreatedAtAction メソッドの使い方

ASP.NET Core(.NET 6)のWEB APIで、CreatedAtActionメソッドの使用方法について解説していきます。

asp.net core
ASP.NET Core

JSON+ファイルのPOSTリクエスト

JSONのみのPOSTリクエスト をWEB API側のアクションで受け付ける場合、

ASP.NET Core (.NET 6) では、JSONの内容がアクションの引数に設定したモデルクラスに対応していたとき、JSONの値を自動的にモデルクラスにバインドしてくれます。

このときのPOSTで送信されるJSONのMIMEタイプ(Content-Type)は「application/json」となっています。

以下がJSONのみのPOSTリクエスト用のアクションメソッドの例です。
この例ではLoginアクションメソッドの引数に設定しているUserモデルクラスにJSONの値がバインドされるようになっています。

// POSTアクションメソッド
// POST: api/User/login
[HttpPost("login")]
public ActionResult Login([FromBody] User user)
{
     // 処理を書く
     return Ok();
}

// Userモデルクラス
public class User
{
     // ユーザー名
     public string UserName { get; set; }
     // パスワード
     public string Password { get; set; }
}

それでは、JSONとファイルを一緒にPOSTで送信する場合も自動的にモデルにバインドされるかというと、そうでもありません。

JSONと同時にファイルをアップロードする場合、上記のJSONのみのときのようにJSONをモデルに自動的にバインドすることができなくなっています。

これは、ファイルをアップロードする場合は、POSTリクエストのMIMEタイプは「mulitpart/form-data」とする必要があり、ASP.NET 側ではファイルと一緒に送信するJSONを正しくJSONであると判別することができないことが原因となっています。

次の見出しでは、JSON+ファイルをPOST送信する場合にJSONを用意したモデルクラスにバインドする実装について解説していきます。

JSON+ファイルのPOSTリクエスト 実装方法

JSON+ファイルをPOST送信する場合にJSONを用意したモデルクラスにバインドするには、カスタムしたモデルバインダーを実装する必要があります。

モデルバインダーは、HTTPリクエストから受信したデータをASP.NET Coreのモデルにバインドするために使用されます。

そしてこのモデルバインダーをカスタムして、multipart/form-data形式でJSONデータを受け取り、指定されたデータ型にバインドするための実装をしていく必要があります。

以下がカスタムモデルバインダーの実装例になります。

// モデルバインダー(IModelBinder) を実装
public class JsonWithFilesFormDataModelBinder : IModelBinder
{
  // bindingContext:バインド対象の値、バインド先のデータ型、およびバインドの構成情報
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }
     // バインド対象のパラメーター名
        string fieldName = bindingContext.FieldName;
        // パラメーターの値を取得
        var valueProviderResult = bindingContext.ValueProvider.GetValue(fieldName);
        // バインドされた値がない場合、処理終了
        if (valueProviderResult == ValueProviderResult.None)
        {
            return Task.CompletedTask;
        }
        else
        {
       // バインドされた値を格納
            bindingContext.ModelState.SetModelValue(fieldName, valueProviderResult);
        }
     // バインドされた値を取得
        string value = valueProviderResult.FirstValue;
        if (string.IsNullOrEmpty(value))
        {
            return Task.CompletedTask;
        }
        try
        {
       // JSONデータを指定されたデータ型にデシリアライズ
            object result = JsonConvert.DeserializeObject(value, bindingContext.ModelType);
       
            bindingContext.Result = ModelBindingResult.Success(result);
        }
        catch (JsonException)
        {
       // 失敗した場合 バインド失敗のリザルトを返す
            bindingContext.Result = ModelBindingResult.Failed();
        }
       // 成功した場合 バインド成功のリザルトを返す
       return Task.CompletedTask;
    }
}

おすすめ記事はコチラ

スマレジ テックファーム 1

スマレジ テックファーム で Webエンジニアとして勤めている tomoです。 今回は株式会社スマレジや私が所属している 「 スマレジ テックファーム 」についてPRしていきたいと思います。 スマレジ ...

2

FromBody 属性を使用して、 ASP.NET Core(.NET 6)のWebAPIでBodyパラメータのJSONを受け取る方法を解説します。 FromBody 属性 POSTやGETで呼び出さ ...

PC picture 3

ASP.NET Core(.NET 6)でCookie認証のタイムアウトを設定する方法を解説します。 Cookieの有効期限について Cookieには通常はタイムアウト(有効期限)を設定します。 基本 ...

4

ASP.NET Core(.NET 6)でクロスオリジンリクエスト ( CORS )を設定する方法を解説します。 簡単に クロスオリジンリクエスト ( CORS )とは何かについても少し解説したいと思 ...

-ASP.NET Core
-,