Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 无法替换ASP.Core 3中的默认JSON协定解析程序_Asp.net Core_Asp.net Core 3.0 - Fatal编程技术网

Asp.net core 无法替换ASP.Core 3中的默认JSON协定解析程序

Asp.net core 无法替换ASP.Core 3中的默认JSON协定解析程序,asp.net-core,asp.net-core-3.0,Asp.net Core,Asp.net Core 3.0,在创建了基于.NETCore3.0框架的基本WebAPI项目之后,所有的API响应都以驼峰的形式出现。我从System.Text.JSON安装了Swashback Swagger+内置JSON序列化程序,具体来说,就是将枚举显示为字符串,一切都和以前一样。然后,我决定切换到NSwag+NewtonSoftJson,因为带有dynamic和expando对象的内置序列化程序存在一些限制。现在,所有API响应都显示在PascalCase中,我既不能更改命名策略,也不能创建自定义契约解析器 示例 问

在创建了基于.NETCore3.0框架的基本WebAPI项目之后,所有的API响应都以驼峰的形式出现。我从System.Text.JSON安装了Swashback Swagger+内置JSON序列化程序,具体来说,就是将枚举显示为字符串,一切都和以前一样。然后,我决定切换到NSwag+NewtonSoftJson,因为带有dynamic和expando对象的内置序列化程序存在一些限制。现在,所有API响应都显示在PascalCase中,我既不能更改命名策略,也不能创建自定义契约解析器

示例

问题

我怀疑在幕后可能有包覆盖了合同解析器。如何确保API服务只使用我在启动时分配的自定义协定解析程序,而忽略所有其他类似设置

自定义JSON协定解析器

public class CustomContractResolver : IContractResolver
{
  private readonly IHttpContextAccessor _context;
  private readonly IContractResolver _contract;
  private readonly IContractResolver _camelCaseContract;

  public CustomContractResolver(IHttpContextAccessor context)
  {
    _context = context;
    _contract = new DefaultContractResolver();
    _camelCaseContract = new CamelCasePropertyNamesContractResolver();
  }

  // When API endpoint is hit, this method is NOT triggered

  public JsonContract ResolveContract(Type value)
  {
    return _camelCaseContract.ResolveContract(value);
  }
}
[ApiController]
public class RecordsController : ControllerBase
{
  [HttpGet]
  [Route("services/records")]
  [ProducesResponseType(typeof(ResponseModel<RecordEntity>), 200)]
  public async Task<IActionResult> Records([FromQuery] QueryModel queryModel)
  {
    var response = new ResponseModel<RecordEntity>();

    return Content(JsonConvert.SerializeObject(response), "application/json"); // NewtonSoft serializer
  }
}
控制器

public class CustomContractResolver : IContractResolver
{
  private readonly IHttpContextAccessor _context;
  private readonly IContractResolver _contract;
  private readonly IContractResolver _camelCaseContract;

  public CustomContractResolver(IHttpContextAccessor context)
  {
    _context = context;
    _contract = new DefaultContractResolver();
    _camelCaseContract = new CamelCasePropertyNamesContractResolver();
  }

  // When API endpoint is hit, this method is NOT triggered

  public JsonContract ResolveContract(Type value)
  {
    return _camelCaseContract.ResolveContract(value);
  }
}
[ApiController]
public class RecordsController : ControllerBase
{
  [HttpGet]
  [Route("services/records")]
  [ProducesResponseType(typeof(ResponseModel<RecordEntity>), 200)]
  public async Task<IActionResult> Records([FromQuery] QueryModel queryModel)
  {
    var response = new ResponseModel<RecordEntity>();

    return Content(JsonConvert.SerializeObject(response), "application/json"); // NewtonSoft serializer
  }
}

仍然不明白为什么自定义契约解析器不是由API端点触发的,但找到了一个组合,可以让我将API切换到camel案例。请随意解释为什么它是这样工作的

services.AddControllers(o => o.RespectBrowserAcceptHeader = true)

  // Options for System.Text.Json don't affect anything, can be uncommented or removed

  //.AddJsonOptions(o =>
  //{
  //  o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
  //  o.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
  //  o.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
  //})

  .AddNewtonsoftJson(o =>
  {
    o.UseCamelCasing(true);
    o.SerializerSettings.Converters.Add(new StringEnumConverter());

    // This option below breaks global settings, so had to comment it

    //o.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver 
    //{
    //  NamingStrategy = new CamelCaseNamingStrategy()
    //};
  });

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
  ContractResolver = new CamelCasePropertyNamesContractResolver()
};
这个想法就是从这个角度出发的


NewtonSoft允许设置全局序列化设置,而不考虑MVC、Web API和其他框架

这是因为Json.NET作为一个独立的nuget包,有自己的内置全局序列化程序设置,与asp.NET配置不同。asp.net将使用其设置,但当您通过调用
JsonConvert.SerializeObject(response)
直接使用Json.net时,Json.net没有asp.net设置的内置知识,而是使用自己的设置。请参阅:。