#c# #http-post #asp.net-core-webapi #dotnet-httpclient #http-get
#c# #http-post #asp.net-core-webapi #dotnet-httpclient #http-get
Вопрос:
У меня есть контроллер веб-API с методом
[HttpPost]
[Authorize]
[Route("[action]")]
public async Task<IActionResult> Authenticate(HttpRequestMessage msg)
{
//msg.Method is always GET
// msg.Content is null
}
Я вызываю его из своего настольного приложения следующим образом:
HttpClient client = new HttpClient(new HttpClientHandler(){AllowAutoRedirect = false});
foreach (var header in headers)
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
await client.PostAsync(requestUrl, content);
Но в методе веб-api свойство msg.Method
всегда является GET и msg.Содержимое равно нулю
Это своего рода перенаправление или другое преднамеренное поведение, когда каждый запрос превращается в GET?
Я попытался изменить его на
[Authorize]
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> C2dSend([FromBody]string request)
{
return Ok();
}
но получил ‘BadRequest’ после вызова.
Единственное, что работает, это заменить string на dynamic:
[Authorize]
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> C2dSend([FromBody]dynamic request)
{
return Ok();
}
Комментарии:
1. Если вместо этого вы отправляете сообщение от Postman, отображается ли оно как GET или POST?
2. Каково пространство имен
HttpPostAttribute
?3. @mjwills это от Microsoft. AspNetCore. Пространство имен Mvc
Ответ №1:
К вашему действию направляются только запросы POST. Вы просто смотрите не в то место — вы пытаетесь привязать тело вашего запроса к HttpRequestMessage
экземпляру. Очевидно, вы передаете здесь что-то еще.
Если вы ищете детали запроса, используйте Request
свойство controller. Он заполняется из контекста contoller, который передается контроллеру во время активации:
[Authorize]
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> C2dSend()
{
// Request.Method is POST here
return Ok();
}
Но вам не нужно использовать его для получения содержимого запроса. Пусть Asp.Net сделайте эту работу за вас — объявите класс model, который имеет те же свойства, что и сериализованный объект, который вы отправляете, и model binder выполнит работу по десериализации за вас:
[Authorize]
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> C2dSend(YourModel blah)
{
// model will be populated automatically from request body
return Ok();
}
Примечание: Существует более простой способ отправки запросов json. Вы можете использовать расширение PostAsJsonAsync из System.Net.Http.Formatting.Расширение