【问题标题】:.Net Core 3.0.100-preview6 - API Json responses are always camelcase, but my classes are not.Net Core 3.0.100-preview6 - API Json 响应总是驼峰式,但我的课程不是
【发布时间】:2019-07-24 12:13:10
【问题描述】:

我有一个 .net core 3.0 preview 6 MVC 应用程序和 API。 在 API 中,我使用第三方类库(我无法更改),它将类属性定义为 Pascal 大小写与 JsonProperty、PropertyName 蛇形大小写例如...

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

more properties ….
}

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

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

我试过了,

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

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

我在骆驼和默认 ContractResolver 上都尝试过 NamingStrategy = null。还尝试将 NamingStrategy 设置为 Snake

但是输出的 Json 没有任何改变,它总是驼峰式的。

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

这是 .net 核心预览中的错误还是缺少其他内容?

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

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

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

【问题讨论】:

标签: c# .net-core json.net json-deserialization json-serialization


【解决方案1】:
Microsoft.AspNetCore.Mvc.NewtonsoftJson

默认情况下不会出现。 尝试将此 nuget 包手动安装到您的服务项目中。这对我有用。

【讨论】:

    【解决方案2】:

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

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

    请务必将此配置添加到 ConfigureServices 方法的底部,它可能会被我不知道的其他内容覆盖。

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      所以我的 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,但这不起作用。

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

      【讨论】:

        【解决方案4】:

        我在将我的 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。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-25
          • 2022-01-15
          • 2014-09-11
          相关资源
          最近更新 更多