我有一个 .net core 3.0 预览版 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 } };
我已经在camel和默认ContractResolver上尝试过NamingStrategy = null。还尝试将 NamingStrategy 设置为 Snake
但是输出的 Json 没有任何改变,它始终是驼峰式的。
我可以看到,通过在 MVC 应用程序中使用 ReadAsStringAsync,生成的字符串是驼峰式大小写的...当我使用 JsonConvert.DeserializeObject 时,属性始终为 null,因为名称或 Json PropertyName 都与生成的字符串中的名称不匹配。
这是 .net core 预览中的错误还是我遗漏了其他内容?
谢谢 Mustafa,您建议的重复问题与我已经尝试过的解决方案有点相同,即将 ContractResolver / NamingStrategy 的设置更改为不同的值......但是,我的问题是没有建议的解决方案似乎对 API 响应有任何影响,它总是以驼峰命名形式返回。
有趣的是,当我将 NamingStrategy 更改为 Snake 时,Swagger 将模式显示为已设置(即蛇),但实际输出仍然是驼峰式!!!
此外,我无法控制基类,因此我无法更改我尝试传输的类的名称/json 属性。
Microsoft.AspNetCore.Mvc.NewtonsoftJson
默认不出现。 尝试将此 nuget 包手动安装到您的服务项目中。这对我有用。
尝试此操作并删除所有
JsonProperty
属性。
从现在开始,如果您不指定任何
JsonProperty
y,它将像这样 CompanyName
like company_name
或 ProPertyName1
like 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
因此,我决定使用 .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 的所有引用,并且一切正常。
我在将 api 从 .netcore 2.2 转换为 .netcore 3 时遇到了这个问题。 即使我的模型是 PascalCase,我的 api 返回的响应也转换为驼峰命名法。 在
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。
试试这个:
builder.Services.AddControllers().AddJsonOptions(jsonOptions => { //防止帕斯卡大小写属性在序列化期间被重命名为驼峰大小写(默认行为) jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null; });
我在 .NET 7.0 中使用它并且它正在工作。