使用 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
指定序列化选项?
一种方法可能是创建一个继承自
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);
}
看起来按照设计,
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);
}