編集:31/10/2017
同じコード/アプローチがAsp.Net Core 2.0でも機能します。主な違いは、asp.netコアでは、web apiコントローラーとMvcコントローラーの両方が単一のコントローラーモデルにマージされることです。あなたの戻り値の型があるかもしれないのでIActionResult
、それの実装の1か(例:OkObjectResult
)
使用する
contentType:"application/json"
JSON.stringify
送信するときに、メソッドを使用してJSON文字列に変換する必要があります。
そして、モデルバインダーはjsonデータをクラスオブジェクトにバインドします。
以下のコードは正常に動作します(テスト済み)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
結果
contentType
プロパティは、JSON形式でデータを送信していることをサーバーに通知します。JSONデータ構造を送信したため、モデルバインディングは適切に行われます。
ajaxリクエストのヘッダーを調べると、Content-Type
値がに設定されていることがわかりますapplication/json
。
contentTypeを明示的に指定しない場合、デフォルトのコンテンツタイプである application/x-www-form-urlencoded;
2015年11月に編集して、コメントで指摘された他の考えられる問題に対処する
複雑なオブジェクトを投稿する
次のようなWeb APIアクションメソッドのパラメーターとして、複雑なビューモデルクラスがあるとします。
public class CreateUserViewModel
{
public int Id {set;get;}
public string Name {set;get;}
public List<TagViewModel> Tags {set;get;}
}
public class TagViewModel
{
public int Id {set;get;}
public string Code {set;get;}
}
そしてあなたのウェブAPIのエンドポイントは
public class ProductController : Controller
{
[HttpPost]
public CreateUserViewModel Save([FromBody] CreateUserViewModel m)
{
// I am just returning the posted model as it is.
// You may do other stuff and return different response.
// Ex : missileService.LaunchMissile(m);
return m;
}
}
この記事の執筆時点では、ASP.NET MVC 6は最新の安定バージョンであり、MVC6では、Web APIコントローラーとMVCコントローラーの両方がMicrosoft.AspNet.Mvc.Controller
基本クラスから継承されています。
クライアント側からメソッドにデータを送信するには、以下のコードが正常に機能するはずです
//Build an object which matches the structure of our view model class
var model = {
Name: "Shyju",
Id: 123,
Tags: [{ Id: 12, Code: "C" }, { Id: 33, Code: "Swift" }]
};
$.ajax({
type: "POST",
data: JSON.stringify(model),
url: "../product/save",
contentType: "application/json"
}).done(function(res) {
console.log('res', res);
// Do something with the result :)
});
モデルバインディングは一部のプロパティでは機能しますが、すべてでは機能しません。どうして ?
[FromBody]
属性でWeb APIメソッドパラメータを装飾しない場合
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
そして、contentTypeプロパティ値を指定せずにモデル(JSON形式ではなく生のjavascriptオブジェクト)を送信します
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
モデルバインディングは、型が複合型/別の型であるプロパティではなく、モデルのフラットプロパティに対して機能します。私たちの場合、Id
およびName
プロパティが適切にパラメータにバインドされますm
、しかし、Tags
プロパティは空のリストになります。
$.post
リクエストを送信するときにデフォルトのContent-Type を使用する短いバージョンを使用している場合にも、同じ問題が発生します。
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});