在 ASP.NET Core MVC 中为 HttpResults 指定 JsonSerializerOptions

问题描述 投票:0回答:2

使用 ASP.NET Core MVC,可以通过多种方式返回结果。

ASP.NET Core Web API 中的控制器操作返回类型 :

  • 具体类型
  • IActionResult
  • ...
  • HttpResult

但是当控制器操作返回

HttpResult
时,ASP.NET Core MVC 序列化选项将被忽略。

示例

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddJsonOptions(
    o => o.JsonSerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.SnakeCaseUpper
);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();
app.MapControllers();

app.Run();

FoosController.cs

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication.Controllers;

[Route("foos")]
public class FoosController
{
    [HttpGet("raw")]
    public Foo Raw() => new Foo();

    [HttpGet("action-result")]
    public IActionResult Action() => new OkObjectResult(new Foo());

    [HttpGet("http-result")]
    public IResult Http() => Results.Ok(new Foo());

    [HttpGet("typed-result")]
    public Ok<Foo> Typed() => TypedResults.Ok(new Foo());
}

public class Foo
{
    public int Id { get; set; }
    public string Label { get; set; } = "";
}

端点

/raw
/action-result
返回 :

{
  "ID": 0,
  "LABEL": ""
}

但是端点

/http-result
/typed-result
返回 :

{
  "id": 0,
  "label": ""
}

如何为

HttpResult
指定序列化选项?

c# asp.net-core asp.net-core-mvc asp.net-core-webapi
2个回答
0
投票

一种方法可能是创建一个继承自

ActionResult
ObjectResult
的自定义
ActionResult<T>
,允许您应用序列化设置。

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;

public class CustomJsonResult : ObjectResult
{
   public CustomJsonResult(object value)
    : base(value)
  {
     this.StatusCode = StatusCodes.Status200OK;
     this.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
     {
        // Apply your serialization settings here
        ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver
        {
            NamingStrategy = new Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy()
        },
        Formatting = Newtonsoft.Json.Formatting.Indented
        // Add more settings as needed
      };
   }
}

然后,您可以在控制器中使用此自定义结果类型:

[HttpGet("http-result")]
public IActionResult Http()
 {
  var foo = new Foo();
  return new CustomJsonResult(foo);
 }

0
投票

看起来按照设计,

HttpResults
设置不会与配置的格式化程序及其设置(此处:Json 序列化选项)一起使用。

来自文档

与 MVC 特定的结果类型不同,HttpResults: 不利用配置的格式化程序。

不利用配置的格式化程序意味着: 某些功能(例如内容协商)不可用。


针对

IResult
设置解决此问题的一种方法是使用适当的序列化选项调用 Results.Json

您没有内容协商,但这是设计使然 - 请参阅链接的文档片段。

[Route("foos")]
public class FoosController
{
    private static readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions
    {
        PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.SnakeCaseUpper
    };

    [HttpGet("http-result")]
    public IResult Http() => Results.Json<Foo>(new Foo(), _jsonSerializerOptions);
}
© www.soinside.com 2019 - 2024. All rights reserved.