Наиболее базовая версия, отвечающая JsonResult
:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
Однако это не поможет решить вашу проблему, потому что вы не можете явно иметь дело с собственным кодом ответа.
Чтобы получить контроль над результатами статуса, вам нужно вернуть a, в ActionResult
котором вы сможете воспользоваться преимуществами этого StatusCodeResult
типа.
например:
// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authorRepository.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
Обратите внимание, что оба приведенных выше примера взяты из отличного руководства, доступного в документации Microsoft: Форматирование данных ответов.
Extra Stuff
Проблема, с которой я сталкиваюсь довольно часто, заключается в том, что я хотел более детальный контроль над моим WebAPI, а не просто использовать конфигурацию по умолчанию из шаблона «Новый проект» в VS.
Давайте удостоверимся, что у вас есть некоторые основы ...
Шаг 1. Настройте свой сервис
Чтобы заставить ваш ASP.NET Core WebAPI отвечать сериализованным объектом JSON при полном контроле кода состояния, вам следует начать с проверки того, что вы включили AddMvc()
службу в свой ConfigureServices
метод, который обычно находится в Startup.cs
.
Важно отметить, что он AddMvc()
будет автоматически включать средство форматирования ввода / вывода для JSON наряду с ответом на другие типы запросов.
Если ваш проект требует полного контроля и вы хотите строго определить свои службы, например, как ваш WebAPI будет вести себя с различными типами запросов, включая application/json
и не отвечать на другие типы запросов (например, стандартный запрос браузера), вы можете определить его вручную с помощью следующий код:
public void ConfigureServices(IServiceCollection services)
{
// Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
// https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs
services
.AddMvcCore(options =>
{
options.RequireHttpsPermanent = true; // does not affect api requests
options.RespectBrowserAcceptHeader = true; // false by default
//options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
//remove these two below, but added so you know where to place them...
options.OutputFormatters.Add(new YourCustomOutputFormatter());
options.InputFormatters.Add(new YourCustomInputFormatter());
})
//.AddApiExplorer()
//.AddAuthorization()
.AddFormatterMappings()
//.AddCacheTagHelper()
//.AddDataAnnotations()
//.AddCors()
.AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}
Вы заметите, что я также включил способ добавления собственных форматировщиков ввода / вывода на случай, если вы захотите ответить на другой формат сериализации (protobuf, thrift и т. Д.).
Кусок кода выше является в основном дубликатом AddMvc()
метода. Тем не менее, мы внедряем каждый сервис «по умолчанию» самостоятельно, определяя каждый сервис вместо того, чтобы идти с предварительно поставленным сервисом с шаблоном. Я добавил ссылку на репозиторий в блок кода, или вы можете проверить это AddMvc()
в репозитории GitHub. ,
Обратите внимание, что есть некоторые руководства, которые попытаются решить эту проблему путем «отмены» настроек по умолчанию, а не просто не реализовывать их в первую очередь ... Если учесть, что мы сейчас работаем с открытым исходным кодом, это избыточная работа , плохой код и откровенно старая привычка, которая скоро исчезнет.
Шаг 2: Создайте контроллер
Я собираюсь показать вам по-настоящему простой, чтобы разобраться в вашем вопросе.
public class FooController
{
[HttpPost]
public async Task<IActionResult> Create([FromBody] Object item)
{
if (item == null) return BadRequest();
var newItem = new Object(); // create the object to return
if (newItem != null) return Ok(newItem);
else return NotFound();
}
}
Шаг 3: Проверьте свои Content-Type
иAccept
Вы должны убедиться, что ваш Content-Type
и Accept
заголовки в вашем запросе установлены правильно. В вашем случае (JSON) вы захотите настроить его на application/json
.
Если вы хотите, чтобы ваш WebAPI отвечал как JSON по умолчанию, независимо от того, что указывает заголовок запроса, вы можете сделать это несколькими способами .
Способ 1
Как показано в статье, которую я рекомендовал ранее ( форматирование данных ответа ), вы можете принудительно установить определенный формат на уровне контроллера / действия. Мне лично этот подход не нравится ... но вот для полноты картины:
Форсирование определенного формата Если вы хотите ограничить форматы ответов для конкретного действия, которое вы можете, вы можете применить фильтр [Производит]. Фильтр [Produces] определяет форматы ответов для определенного действия (или контроллера). Как и большинство фильтров, это может быть применено к действию, контроллеру или глобальной области видимости.
[Produces("application/json")]
public class AuthorsController
[Produces]
Фильтр заставит все действия в пределах
AuthorsController
вернуть JSON-форматированные ответы, даже если другие форматтеры были сконфигурированы для приложения , и клиент предоставил Accept
заголовок запрашивающий другой, доступный формат.
Способ 2
Мой предпочтительный метод заключается в том, чтобы WebAPI отвечал на все запросы в запрошенном формате. Тем не менее, в случае, если он не принимает запрошенный формат, откат к стандартному (т.е. JSON)
Во-первых, вам нужно зарегистрировать это в ваших настройках (нам нужно переработать поведение по умолчанию, как отмечалось ранее)
options.RespectBrowserAcceptHeader = true; // false by default
Наконец, просто переупорядочив список форматеров, которые были определены в компоновщике сервисов, веб-хост по умолчанию будет использовать тот форматтер, который вы размещаете в верхней части списка (то есть позицию 0).
Дополнительную информацию можно найти в этой записи блога .NET Web Development and Tools.
CreatedAtRoute
метод и т. Д.