.Net Core 3.0.100-preview6 - API Json 响应总是驼峰式,但我的 类 不是

.Net Core 3.0.100-preview6 - API Json responses are always camelcase, but my classes are not

我有一个 .net core 3.0 preview 6 MVC 应用程序和 API。 在 API 中,我正在使用第三方 class 库(我无法更改),它将 class 属性定义为使用 Json[=51 的 Pascal 大小写=], 属性名称蛇形大小写,例如...

public class Company
{
[JsonProperty(PropertyName = "company_name")]
public string CompanyName { get; set; }

more properties ….
}

问题是,当我通过 api 提供这些时,它们以 Camel 大小写(.net core 3 的默认设置)到达 MVC 应用程序...然后无法反序列化回class 模型。

无论我尝试什么,API 总是生成驼峰式 JSon,例如。上面的 属性 将被称为 companyName.

我试过了,

options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver { NamingStrategy = new CamelCaseNamingStrategy { OverrideSpecifiedNames = true } };

options.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new DefaultNamingStrategy { OverrideSpecifiedNames = true } };

我已经在 camel 和默认的 ContractResolver 上尝试了 NamingStrategy = null。还尝试将 NamingStrategy 设置为 Snake

但输出的 Json 没有任何变化,它始终是驼峰式的。

我可以通过在 MVC 应用程序中使用 ReadAsStringAsync 看到生成的字符串是驼峰式大小写...我在使用 JsonConvert.DeserializeObject 时,属性始终为 null,因为名称或 Json 属性名称与结果字符串中的名称匹配。

这是 .net Core 预览中的错误还是遗漏了其他内容?

谢谢 Mustafa,您建议的副本与我已经尝试过的解决方案有点相同,即将 ContractResolver / NamingStrategy 的设置更改为不同的值....但是,我的问题是 none 的建议解决方案似乎对 API 响应有任何影响,它总是以驼峰形式返回。

有趣的是,当我将 NamingStrategy 更改为 Snake 时,Swagger 将模式显示为已设置(即蛇),但实际输出仍然是驼峰式!!!

此外,我无法控制基础 classes,因此我无法更改我尝试传输的 classes 的名称/json 属性。

试试这个并删除所有 JsonProperty 属性。

从现在开始,如果您不指定任何 JsonPropertyy,它将像这样 CompanyNamecompany_nameProPertyName1pro_perty_name1。在这个例子中将解释 属性 名称的概念。

并确保将此配置添加到 ConfigureServices 方法的底部,它可能会被其他我不知道的东西覆盖。

services.AddMvc().AddJsonOptions(options =>
{
    options.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() };
});

不太确定问题出在哪里,但感觉这与 Newtonsoft.Json、Json.Net、Swagger 的混合使用以及我使用 Microsoft.AspNet.WebApi.Client 得到 HttpContent.ReadAsAsync…. 都具有不同的 Json 的

因此,我决定重新开始使用一个真正简单的应用程序,并 api 使用 .Net Core 预览中包含的新 System.Text.Json(以及其他库的 none)。也不使用 HttpContent.ReadAsAsync 而是将响应作为字符串读取,然后使用新库 (System.Text.Json)

反序列化

这样做我遇到了完全相同的问题......。 属性 名称或 Json PropertyName 都不匹配 api 返回字符串中的名称,即 class 属性 名称 = "CompanyName" 和 Json PropertyName = "company_name" 和 api 提供的 json 名称 = "companyName"。所以反序列化时没有设置值。

但是,在新的 System.Text.Json 选项中,我可以指定 PropertyNameCaseInsensitive = true,这解决了我的问题,现在 companyName 确实等于 CompanyName 并且反序列化时 class 模型值设置正确.

所以我的 api 调用方法最终看起来像这样...

        using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format("Companies?aCompanyName={0}", aCompanyName));
        using HttpResponseMessage response = await Client.SendAsync(request);
        string content = await response.Content.ReadAsStringAsync();
        if (response.IsSuccessStatusCode == false)
        {
            throw new ApiException
            {
                StatusCode = (int)response.StatusCode,
                Content = content
            };
        }
        _JsonOptions = new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        };
        return JsonSerializer.Deserialize<IEnumerable<Company>> (content, _JsonOptions);

我确实尝试在启动时全局设置 JsonSerializerOptions class,但这没有用。

我已将此方法转移到我应用程序中的所有 http 调用,删除了对 Newtonsoft 的所有引用,一切正常。

Microsoft.AspNetCore.Mvc.NewtonsoftJson

没有默认出现。 尝试将此 nuget 包手动安装到您的服务项目。这对我有用。

我在将我的 api 从 .netcore 2.2 转换为 .netcore 3 时遇到了这个问题。 尽管我的模型是 PascalCase,但我的 api 正在返回转换为 camelCase 的响应。 在 startup.cs:

.netcore 2:

services.AddMvc()
    .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

.netcore 3:

// keeps the casing of models when serializing to json (default is converting to camelCase)
services.AddMvc()
    .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null); 

这意味着您不需要导入 newtonsoft.json。