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"));
}


но ответ от сервера странный, как на изображении ниже:



enter image description here



Я просто хочу, чтобы контроллер Web API возвращал JSON с помощью Код состояния HTTP, как я сделал в Web API 2.

704   6  

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 AuthorsController

The [Produces] фильтр принудит все действия внутри AuthorsController для возврата ответов в формате JSON, даже если другие форматеры были настроены для применения и клиентом, при условии Ан Accept заголовок запрашивает другой, доступный формат.

Способ 2 Мой предпочтительный метод заключается в том, чтобы WebAPI отвечал на все запросы с запрошенным форматом. Однако в том случае, если он не принимает запрошенный формат, тогда откат по умолчанию (т. е. JSON)

во-первых, вам нужно будет зарегистрировать это в своих опциях (нам нужно переработать поведение по умолчанию, как отмечалось ранее)

options.RespectBrowserAcceptHeader = true; // false by default

наконец, просто переупорядочивая список форматировщиков, которые были определены в построителе служб, веб-хост будет по умолчанию использовать форматировщик, который вы размещаете в верхней части списка (т. е. позиция 0).

дополнительную информацию можно найти в этом .NET Web Разработка и инструменты запись в блоге

у вас есть предопределенные методы для самых распространенных кодов состояния.

  • Ok(result) возвращает 200 ответ
  • CreatedAtRoute возвращает 201 + новый URL ресурса
  • NotFound возвращает 404
  • BadRequest возвращает 400 etc.

посмотреть 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" });
}

обратите внимание, что

  1. он возвращается с 200 OK код состояния (это Ok типа ObjectResult)
  2. он выполняет согласование контента, т. е. он вернется на основе 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" };
}

обратите внимание, что

  1. обеспечивает JSON двумя разными способами.
  2. оба игнорируют содержимое ведение переговоров.
  3. Первый метод применяет JSON с определенным сериализатором Json(object).
  4. Второй способ делает то же самое с помощью (это 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

    Ничего не найдено.