.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
属性。
从现在开始,如果您不指定任何 JsonProperty
y,它将像这样 CompanyName
像 company_name
或 ProPertyName1
像 pro_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。
我有一个 .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
属性。
从现在开始,如果您不指定任何 JsonProperty
y,它将像这样 CompanyName
像 company_name
或 ProPertyName1
像 pro_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。