[解決済み] Web API メソッドに json の POST データをオブジェクトとして渡すにはどうすればよいですか?
質問
ASP.NET MVC4 Web APIアプリケーションでは、顧客を保存するためにpostメソッドを定義しています。 顧客は、POSTリクエストボディにjson形式で渡されます。 postメソッドのCustomerパラメータは、プロパティにNULL値を含んでいます。
投稿されたデータが顧客オブジェクトとして渡されるようにするには、どのように修正すればよいですか?
フォームを投稿するjavascriptのメソッドで変更する方法が分からないので、できればContent-Type: application/x-www-form-urlencodedを使用したいです。
コントローラです。
public class CustomersController : ApiController {
public object Post([FromBody] Customer customer)
{
return Request.CreateResponse(HttpStatusCode.OK,
new
{
customer = customer
});
}
}
}
public class Customer
{
public string company_name { get; set; }
public string contact_name { get; set; }
}
リクエストしてください。
POST http://localhost:52216/api/customers HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
{"contact_name":"sdfsd","company_name":"ssssd"}
解決方法は?
EDIT : 31/10/2017
同じコード/アプローチで
Asp.Net Core 2.0
と同じです。大きな違いは、asp.net core では、Web API コントローラと Mvc コントローラの両方が、単一のコントローラモデルに統合されていることです。そのため、戻り値の型は
IActionResult
またはその実装(例.
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;}
}
そして、Web 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 :)
});
モデルバインディングは、いくつかのプロパティで動作しますが、すべてではありません! なぜでしょうか?
Web api のメソッドパラメータを
[FromBody]
属性
[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);
});
関連
-
Vueの「データを聴く」原則を解説
-
[解決済み】ExpressJS : res.redirect()が期待通りに動かない?
-
[解決済み] JavaScriptのオブジェクトが空であることをテストするにはどうすればよいですか?
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] オブジェクトが配列であるかどうかを確認するにはどうすればよいですか?[重複]。
-
[解決済み] Node.jsのプログラムにコマンドライン引数を渡すにはどうしたらいいですか?
-
[解決済み] jQueryでフォームデータをJavaScriptオブジェクトに変換する
-
[解決済み] JSON文字列を安全にオブジェクトに変換する
-
[解決済み] Chromeを使用してASP.NET Web APIがXMLの代わりにJSONを返すようにするにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueはランニングライト形式のテキストを水平方向にスクロールする機能を実装している
-
vue3.0プロジェクトのアーキテクチャを構築するための便利なツール
-
Javascript Bootstrapのグリッドシステム、ナビゲーションバー、ローテーションの説明
-
vueはopenlayersを使用してスカイマップとガオードマップをロードする
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み】JavaScriptの配列でforEachが関数でない不具合
-
[解決済み】awaitは非同期関数でのみ有効です。
-
[解決済み】JavaScriptエラー(Uncaught SyntaxError: Unexpected end of input)
-
HTML5 LocalStorage ローカルストレージとセッションストレージの使用法
-
フロントエンド null のプロパティ 'disabled' を読み取れない 問題が解決された