Web API で動作する POST リクエストを取得しようとしています。以下は私の API コントローラーです。
public class WebsController : ApiController
{
[HttpPost]
public void PostOne(string id)
{
}
[HttpPost]
public void PostTwo(Temp id)
{
}
}
アクションを考慮に入れるために、WebAPI ルートを変更しました。Temp モデルは次のようになります。
public class Temp
{
public string Id { get; set; }
}
私の見解はこんな感じです
@using (Ajax.BeginForm(new AjaxOptions
{
Url = "/api/webs/postone",
HttpMethod = "post"
}))
{
<input name="id" id="id" value="2" />
<input type="submit" value="submit" />
}
上記のコードは、このようにパラメータの前に [FromBody] 属性を配置しない限り、postone ではまったく機能しません。
[HttpPost]
public void PostOne([FromBody]string id)
{
}
その後、アクションにヒットしますが、ID はまだ null です。テキスト ボックスの値は入力されません。
しかし、Url
の をモデルを取得するAjax.BeginForm
に変更すると、正常に動作し、フィールドにはテキストボックス内の適切な値が表示されます。posttwo
Temp
Id
なぜこのようなことが起こるのか、また、どうすれば単純な値を Web API アクションに投稿できるのか、どなたか説明していただけませんか? つまり、複雑な型はバインドできるのに、単純な型はバインドできないのはなぜでしょうか。
ベストアンサー1
この質問をしてからかなり時間が経ちました。今はより明確に理解しているので、他の人の役に立つように、より完全な回答を載せようと思います。
Web API では、パラメータのバインディングがどのように行われるかを覚えるのは非常に簡単です。
- 単純な型を指定すると
POST
、Web APIはURLからバインドを試みます 複雑な型を指定すると
POST
、Web API はリクエストの本文からバインドしようとします (media-type
フォーマッタが使用されます)。URL から複合型をバインドする場合は、
[FromUri]
アクション パラメータで を使用します。この制限は、データの長さと URL の文字数制限を超えるかどうかによって決まります。public IHttpActionResult Put([FromUri] ViewModel data) { ... }
リクエスト本文から単純な型をバインドする場合は、アクション パラメータで [FromBody] を使用します。
public IHttpActionResult Put([FromBody] string name) { ... }
補足として、PUT
何かを更新するためのリクエスト (単なる文字列) を作成しているとします。URL に追加せず、モデル内の 1 つのプロパティのみを持つ複合型として渡すことにした場合、data
jQuery ajax のパラメーターは以下のようになります。データ パラメーターに渡すオブジェクトには、プロパティ名が空のプロパティが 1 つだけあります。
var myName = 'ABC';
$.ajax({url:.., data: {'': myName}});
Web API アクションは以下のようになります。
public IHttpActionResult Put([FromBody] string name){ ... }
この asp.net ページですべてが説明されています。http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api