APIを呼び出すアクションがWebプロジェクトにあります
[HttpPost]
public async Task<IActionResult> ExpireSurvey(int id)
{
var token = await HttpContext.GetTokenAsync("access_token");
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var path = "/api/forms/ExpireSurvey";
var url = Domain + path;
var data = JsonConvert.SerializeObject(id);
HttpContent httpContent = new StringContent(data, Encoding.UTF8, "application/json");
var response = await client.PutAsync(url, httpContent);
return Json(response);
}
}
APIプロジェクトでは、これは次のように受信されます。
[HttpPut]
public IActionResult ExpireSurvey([FromBody] int surveyId)
{
_repository.ExpireSurvey(surveyId, expiryDate);
return Ok();
}
これは正常に動作しますが、int idとDateTime変数を渡したい場合、どのようにシリアル化して両方をHttpContentに渡しますか? DTOオブジェクトでそれを行うことができますが、フィールドが2つしかないときにDTOオブジェクトをセットアップしたくありません。
このような匿名型を使用できます
var x = new { id = 2, date = DateTime.Now };
var data = JsonConvert.SerializeObject(x);
データを受信するときは、[FromBody]パラメータを1つだけ持つことができます。したがって、それは複数のパラメーターを受け取る場合には機能しません(URLに1つを除くすべてを入れることができない場合を除く)。 DTOを宣言したくない場合は、次のような動的オブジェクトを使用できます。
[HttpPost]
public void Post([FromBody] dynamic data)
{
Console.WriteLine(data.id);
Console.WriteLine(data.date);
}
ただし、匿名型と動的変数を無理に使用しないでください。これらはJSONを操作するのに非常に便利ですが、すべての型チェックが失われるため、C#を操作するのに非常に便利です。
ASP.NET CoreはRESTベースであり、RESTは基本的にresourcesの概念を扱います)であることを認識すると役立つと思います。一般的な考え方は、ここではDTOと呼んでいるものを用意する必要があるということです。つまり、明確で無関係なデータのビットを投稿するのではなく、何かを表すobjectを投稿します。
これは、Swaggerなどを混ぜてAPIのドキュメントを生成する場合にますます重要になります。作成したオブジェクトはそのドキュメントの一部になり、APIの利用者にアプリの開発をフォローするためのテンプレートを提供します。
長くても短くても、リソース/オブジェクト/ DTO /その他の概念を採用すると思います。 モデル APIが使用するデータ。これは、APIの開発者として、およびAPIのコンシューマーの両方に役立ちます。
以下の例のように、URLとして複数のパラメータを渡すことができます
パラメータ名は同じである必要があります(大文字と小文字は区別されません)。名前が一致しない場合、パラメータの値は設定されません。
[HttpPost]
[Route("{surveyId}/{expiryDate}")]
public IActionResult Post(int surveyId, DateTime expiryDate)
{
return Ok(new { surveyId, expiryDate });
}
呼び出しURL
http://localhost:[port]/api/[controller]/1/3-29-2018
辞書でそれができる
Dictionary<string, object> dict = new Dictionary<string, object>();
dict["id"] = 1
dict["date"] = DateTime.Now;
JsonConvert.SerializeObject(dict);
上記の回答に基づいて、私は次のコードを機能させました。これが誰かを助けることを願っています! (もちろん私を正しい軌道に乗せてくれた他の人に感謝します)
/// <summary>
/// Post api/dostuff/{id}
[HttpPost]
[Route("dostuff/{id}")]
public async Task<IActionResult> DoStuff([FromBody]Model model, int id)
{
// Both model and id are available for use!
}