Я пытаюсь поэкспериментировать с основным веб-API asp.net, поэтому я сделал несколько простых API с таким контроллером:
[ApiController]
[Route("MyController")]
public class MyController : ControllerBase
{
[HttpGet]
[Route("GetResult")]
public IActionResult GetResult(string param1, string param2= null, SomeClassObj obj = null)
{ .... }
}
Я запустил API локально и отправил GET-запрос почтальону:
https://localhost:5001/MyController/GetResult?param1=someString
Я получил ошибку: 415 Неподдерживаемый тип носителя
Что мне здесь не хватает, чтобы это могло работать?
Какую версию .NET Core вы используете?
Попробуйте выполнить запрос из браузера и посмотрите, будет ли у вас такой же результат.
Кроме того, вы уверены, что делаете запрос GET, а не POST в Postman? Вы не должны получать ошибки 415 для запросов GET, особенно если вы не отправляете никакого тела.
Эта ошибка в основном возникает, когда вы пытаетесь отправить тело сообщения, но не указали тип носителя в заголовке Content-Type
.
Убедитесь, что запрос GET и ваше тело пусто.
Решение после редактирования сообщения:
Когда вы пытаетесь проанализировать объект DTO (SomeClassObj
), вы должны указать, откуда должны браться значения. Чтобы исправить ваш конкретный случай, добавьте атрибут [FromQuery]
перед SomeClassObj
.
Ваш код должен выглядеть так:
[ApiController]
[Route("MyController")]
public class MyController : ControllerBase
{
[HttpGet]
[Route("GetResult")]
public IActionResult GetResult(string param1, string param2= null, [FromQuery]SomeClassObj obj = null)
{ .... }
}
Это говорит синтаксическому анализатору извлечь данные из строки запроса. Это решит проблему 415
. Однако, если вы хотите выполнить привязку к сложным типам, особенно на get, ознакомьтесь с этими темами: Привязка модели ASP.NET CORE 3.1 и эта проблема, поскольку вы, скорее всего, столкнетесь с проблемами при анализе вашего объекта DTO.
@YonatanNir Ты что-то упускаешь. Пожалуйста, отредактируйте свой первоначальный пост, указав полный код, который вы используете в контроллере. Также, на всякий случай, прикрепите скриншот запроса, который вы делаете в браузере и почтальоне.
ОК, я извиняюсь, так как я написал здесь старый код. В сигнатуре GetResult был дополнительный параметр, который не был строкой, и это тот, кто его вызвал.
Да, скорее всего, вы пытаетесь использовать объект DTO. В любом случае обновите свой первоначальный пост, чтобы мы могли дать вам правильное решение.
отредактировано. Вы также можете отредактировать ответ, и я приму его.
@YonatanNir Я добавил правку. Пожалуйста, обратите внимание на часть о привязке модели, поскольку вы, скорее всего, столкнетесь с этой проблемой довольно скоро.
Я получал ту же ошибку после вызова WEB API из .NET MVC.
Как предложил @zhulien, я изменил [FromBody]
на [FromForm]
в WebAPI, у меня это работает нормально.
Метод .NET Core WebAPI.
public async Task<IActionResult> Login([FromForm] LoginModel loginInfo)
{ // JWT code here }
Метод действия .Net Core MVC.
public async void InvokeLoginAPIAsync(string endPoint, string userName, string pwd)
{
configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
baseUrl = configuration["Application:BaseAPI"] ?? throw new Exception("Unable to get the configuration with key Application:BaseAPI");
string targetUrl = string.Format("{0}/{1}", baseUrl, endPoint);
using (HttpClient deviceClient = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post, targetUrl);
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("userName", userName),
new KeyValuePair<string, string>("password", pwd)
};
request.Content = new FormUrlEncodedContent(data);
using (var response = await deviceClient.SendAsync(request))
{
if (response.StatusCode == HttpStatusCode.OK)
{
TempData["Response"] = JsonConvert.SerializeObject(response.Content);
}
}
}
}
Спасибо, @KingRaja. Хитрость заключалась в [FromForm]
; Тип содержимого AJAX в jQuery по умолчанию — «application/x-www-form-urlencoded; charset=UTF-8». Также пришлось использовать это в вызове AJAX: data: { "": myStringValue }
. Если я отправил сериализованный объект и использовал DTO для сопоставления, [FromBody]
работал нормально. Не знаю, почему это все так больно :)
Используйте атрибут [FromForm]
перед каждым аргументом в функции контроллера.
ядро .net 3.1. В почтальоне это GET запрос и тела нет. Когда скопировал тот же запрос в браузер, я снова получил ошибку 415: введите "tools.ietf.org/html/rfc7231#section-6.5.13" title "Unsupported Media Type" status 415 traceId "|f42c992c-498a76ef71e4af5e ."