использование System.Text.JSON с ASP.NET Core 3: определиться с выводом JSON на конечной точке? - PullRequest
2 голосов
/ 18 октября 2019

С помощью ASP.NET Core 3 и System.Text.Json вы можете вернуть довольно отформатированный JSON, добавив

services.AddControllers().AddJsonOptions(
options => options.JsonSerializerOptions.WriteIndented = true);

в файл Startup.cs ...

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddApiVersioning(o =>
    {
        o.AssumeDefaultVersionWhenUnspecified = true;
        o.DefaultApiVersion = new ApiVersion(1, 0);
    });

    services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
}

. ... но это означает, что он довольно печатает весь вывод JSON глобально для всех конечных точек.

Есть ли способ определить симпатичное или нет на уровне конечной точки, например, по строке запроса "pretty = true"?:

https://localhost:5001/api/v1/persons/1231221.json?pretty=true

В ваших Controllers / PersonController.cs вы можете сделать ...

[HttpGet]
[Route("/api/v{version:apiVersion}/[controller]/{id}.json")]
public IActionResult PersonAsJson([FromRoute] int id, [FromQuery] bool pretty = false)
{
    var person = new Person(id)

    // ...

    if (pretty)
    {
        Response.Headers.Add("Content-Type", "text/plain");

        return Ok(JsonSerializer.Serialize(
            person,
            new JsonSerializerOptions { WriteIndented = true }));
    }

    // non pretty output if there's no
    // services.AddControllers().AddJsonOptions(
    //    options => options.JsonSerializerOptions.WriteIndented = true);
    // in Startup.cs

    Response.Headers.Add("Content-Type", "application/json");

    return Ok(person);
}

... но это, очевидно, возвращает неправильный тип содержимого для довольно отформатированного JSON.

Какое-нибудь решение для этого я пока не вижу?

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Поскольку оба ваших ответа должны удовлетворять Content-Type: application/json, я бы сделал это следующим образом:

[HttpGet]
[Route("/api/v{version:apiVersion}/[controller]/{id}.json")]
public IActionResult PersonAsJson([FromRoute] int id, [FromQuery] bool pretty = false)
{
    var person = new Person(id)

    // ...

    Response.Headers.Add("Content-Type", "application/json");

    if (pretty)
    {
        return Ok(JsonSerializer.Serialize(
            person,
            new JsonSerializerOptions { WriteIndented = true }));
    }

    // non pretty output if there's no
    // services.AddControllers().AddJsonOptions(
    //    options => options.JsonSerializerOptions.WriteIndented = true);
    // in Startup.cs

    return Ok(person);
}

Нет необходимости устанавливать заголовки дважды.

0 голосов
/ 18 октября 2019

Это может быть тип содержимого:

    Response.Headers.Add("Content-Type", "application/json;");

будет выглядеть так:

if (pretty)
{
    Response.Headers.Add("Content-Type", "application/json;");

    return Ok(JsonSerializer.Serialize(
        person,
        new JsonSerializerOptions { WriteIndented = true }));
}
...