ASP.NET ядро возвращает JSON с кодом состояния
Я ищу правильный способ вернуть JSON с кодом состояния HTTP в моем контроллере .NET Core Web API. Я использую его так:
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
Это было в приложении 4.6 MVC, но теперь с .NET Core у меня, похоже, нет этого IHttpActionResult у меня есть ActionResult и используя такой:
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
но ответ от сервера странный, как на изображении ниже:

Я просто хочу, чтобы контроллер Web API возвращал JSON с помощью Код состояния HTTP, как я сделал в Web API 2.
6 ответов:
самая основная версия отвечает с
JsonResult- это:// GET: api/authors [HttpGet] public JsonResult Get() { return Json(_authorRepository.List()); }однако, это не поможет с вашей проблемой, потому что вы не можете явно иметь дело с вашим собственным кодом ответа.
способ получить контроль над результатами состояния, вам нужно вернуть
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:Форматирование Данных Ответа
Дополнительные Вещи
проблема, с которой я сталкиваюсь довольно часто, заключается в том, что мне нужен более детальный контроль над моим 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 Как показано в статье, которую я рекомендовал ранее (Форматирование Данных Ответа) вы можете заставить a определенный формат на уровне контроллера / действия. Лично мне такой подход не нравится... но вот для полноты картины:
форсирование определенного формата если вы хотите ограничить форматы ответов для конкретного действия, вы можете применить [Производит] фильтр. Фильтр [производит] определяет ответ форматы для конкретного действия (или контроллера). Как и большинство фильтров, это смогите быть приложено на действии, регуляторе, или глобальном масштаб.
[Produces("application/json")] public class AuthorsControllerThe
[Produces]фильтр принудит все действия внутриAuthorsControllerдля возврата ответов в формате JSON, даже если другие форматеры были настроены для применения и клиентом, при условии АнAcceptзаголовок запрашивает другой, доступный формат.Способ 2 Мой предпочтительный метод заключается в том, чтобы WebAPI отвечал на все запросы с запрошенным форматом. Однако в том случае, если он не принимает запрошенный формат, тогда откат по умолчанию (т. е. JSON)
во-первых, вам нужно будет зарегистрировать это в своих опциях (нам нужно переработать поведение по умолчанию, как отмечалось ранее)
options.RespectBrowserAcceptHeader = true; // false by defaultнаконец, просто переупорядочивая список форматировщиков, которые были определены в построителе служб, веб-хост будет по умолчанию использовать форматировщик, который вы размещаете в верхней части списка (т. е. позиция 0).
дополнительную информацию можно найти в этом .NET Web Разработка и инструменты запись в блоге
у вас есть предопределенные методы для самых распространенных кодов состояния.
Ok(result)возвращает200ответCreatedAtRouteвозвращает201+ новый URL ресурсаNotFoundвозвращает404BadRequestвозвращает400etc.посмотреть
BaseController.csиController.csдля списка всех методов.но если вы настаиваете, вы можете использовать
StatusCodeдля установки a пользовательский код, но вы действительно не должны, так как это делает код менее читаемым, и вам придется повторить код для установки заголовков (например, дляCreatedAtRoute).public ActionResult IsAuthenticated() { return StatusCode(200, Json("123")); }
С ASP.NET ядро 2.0 идеальный способ вернуть объект из
Web API(который унифицирован с MVC и использует тот же базовый классController) составляетpublic IActionResult Get() { return new OkObjectResult(new Item { Id = 123, Name = "Hero" }); }обратите внимание, что
- он возвращается с
200 OKкод состояния (этоOkтипаObjectResult)- он выполняет согласование контента, т. е. он вернется на основе
Acceptзаголовок в запросе. ЕслиAccept: application/xmlотправляется в запросе, он вернется какXML. Если ничего не отправлено,JSONпо умолчанию.если он должен направить С определенным кодом состояния используйте
ObjectResultили . Оба делают то же самое и поддерживают согласование контента.return new ObjectResult(new Item { Id = 123, Name = "Hero" }) { StatusCode = 200 }; return StatusCode( 200, new Item { Id = 123, Name = "Hero" });если вы хотите вернуться в JSON-формате, есть несколько способов
//GET http://example.com/api/test/asjson [HttpGet("AsJson")] public JsonResult GetAsJson() { return Json(new Item { Id = 123, Name = "Hero" }); } //GET http://example.com/api/test/withproduces [HttpGet("WithProduces")] [Produces("application/json")] public Item GetWithProduces() { return new Item { Id = 123, Name = "Hero" }; }обратите внимание, что
- обеспечивает
JSONдвумя разными способами.- оба игнорируют содержимое ведение переговоров.
- Первый метод применяет JSON с определенным сериализатором
Json(object).- Второй способ делает то же самое с помощью (это
ResultFilter) СcontentType = application/jsonподробнее о них читайте в официальные документы. Узнайте о фильтры здесь.
простой класс модели, который используется в образцах
public class Item { public int Id { get; set; } public string Name { get; set; } }
самый простой способ, который я придумал:
return new JsonResult(result) { StatusCode = 201 // Status code here };
Это мое самое простое решение:
public IActionResult InfoTag() { return Ok(new {name = "Fabio", age = 42, gender = "M"}); }или
public IActionResult InfoTag() { return Json(new {name = "Fabio", age = 42, gender = "M"}); }
пожалуйста см. ниже код, вы можете управлять несколькими кодами состояния с разным типом JSON
public async Task<HttpResponseMessage> GetAsync() { try { using (var entities = new DbEntities()) { var resourceModelList = entities.Resources.Select(r=> new ResourceModel{Build Your Resource Model}).ToList(); if (resourceModelList.Count == 0) { return this.Request.CreateResponse<string>(HttpStatusCode.NotFound, "No resources found."); } return this.Request.CreateResponse<List<ResourceModel>>(HttpStatusCode.OK, resourceModelList, "application/json"); } } catch (Exception ex) { return this.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "Something went wrong."); } }
Comments