WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

ASP.NET Web API のバインディング (2)

by WebSurfer 2019年3月6日 14:47

ASP.NET Web API に、フォームデータ name=value の name に C# の識別子に使えない文字が含まれて POST されてくる場合、どのように value を取得するかを書きます。実際にそんなケースはなさそうなので、役に立たない情報かもしれませんが。(笑)

Web API のバインディング

一般的なバインディングの話は先の記事「ASP.NET Web API のバインディング」に書きました。その記事のコードの Post メソッドに "AAA:Id=6&AAA:Name=ガッチャマンの息子" という文字列がフォームデータとして送信されてくる場合を考えます。(注:当然、送信前に文字列は URL エンコードされます)

フォームデータが "AAA:Id=6" というように一つだけなら、例えば先の記事の Put の場合のように送信側で data:"=AAA:Id=6" として受信側で Put(int id, [FromBody] string name) の name に文字列として取得できますが、"AAA:Id=6&AAA:Name=ガッチャマンの息子" のように 2 つ以上あると組み込みのフォーマッター・モデルバインダーではむりそうです(何故か 1 つ目の "AAA:Id=6" しか取得できません)。

と言って、先の記事の例の Post(Hero postedHero) ようにアクションメソッドの引数をコンプレックス型にはできません。何故なら、コロン ':' は C# の識別子の文字としては使えませんので、AAA:Id や AAA:Name という名前のプロパティが定義できませんから。

ではどうするかと言うと、先の記事でも紹介した MSDN Blog「How WebAPI does Parameter Binding」の記事の最初のコードにあるように HttpRequestMessage を引数に持つメソッドで取得するのがよさそうです。

具体的には以下のコードのようにします。

public async Task<List<Hero>> Post(HttpRequestMessage request)
{
    HttpContent content = request.Content;
    string str = await content.ReadAsStringAsync();
    NameValueCollection formData = 
        await content.ReadAsFormDataAsync();
    string str1 = formData["AAA:Id"];
    string str2 = formData["AAA:Name"];
    Hero postedHero = 
        new Hero { Id = int.Parse(str1), Name = str2 };
    heroes.Add(postedHero);
    return heroes;
}

そうすれば、上の画像に示したように HttpContent.ReadAsFormDataAsync メソッドでフォームデータを取得できます。

クライアント側はボディに設定する文字列を URL エンコードすること、要求ヘッダに Content-Type: application/x-www-form-urlencoded; charset=UTF-8 を含めることを忘れないようにしてください。

Tags: , ,

Web API

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar