为何AuthTokenResponse响应对象除AuthTokenType外其余属性均为Null?
问题原因分析
你的问题核心是前后端序列化/反序列化规则不匹配:
- 后端ASP.NET Core默认使用
System.Text.Json,序列化时会将C#属性名转为驼峰格式(比如AccessToken→accessToken),但你在AuthTokenResponse类上标记的[DataMember(Name="access_token")]是DataContractSerializer或Newtonsoft.Json的DataContract模式专用特性,System.Text.Json默认不识别这些特性,所以后端实际返回的JSON键是驼峰格式,而非你指定的下划线命名。 - 客户端使用的
ReceiveJson<AuthTokenResponse>(推测是Flurl或类似HttpClient扩展),其反序列化器默认遵循DataContract规则,会去匹配access_token、token_type这类下划线命名的键,但后端返回的是accessToken、tokenType,导致匹配失败,这些属性被赋值为null;而AuthTokenType没有标记[DataMember],客户端反序列化时直接匹配驼峰格式的authTokenType,所以能正确获取值。
解决方案
以下三种方案任选其一即可:
方案1:修改后端序列化配置,支持DataContract特性
在ASP.NET Core的配置中,让System.Text.Json识别[DataContract]和[DataMember]特性,这样后端会按照你指定的下划线命名输出JSON:
// Program.cs 或 Startup.cs builder.Services.AddControllers() .AddJsonOptions(options => { // 可选:开启大小写不敏感,增强兼容性 options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; // 添加DataContract解析器 options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { JsonDataContractResolver.ModifyTypeInfo } }; });
方案2:调整客户端反序列化规则,匹配后端驼峰命名
如果不想修改后端,直接让客户端的反序列化器适配后端的驼峰格式:
若使用Flurl(默认用Newtonsoft.Json):
// 全局配置(建议在程序启动时执行) FlurlHttp.Configure(settings => { settings.JsonSerializer = new NewtonsoftJsonSerializer(new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore }); });
若直接使用System.Text.Json:
var authToken = await [url] .AddAuthHeaders(config) .PostJsonAsync(new AuthTokenRequest { GrantType = "test", ClientId = "test", ClientSecret = "test", Audience = "test" }) .ReceiveJson<AuthTokenResponse>(new JsonSerializerOptions { // 开启大小写不敏感,自动匹配驼峰键 PropertyNameCaseInsensitive = true });
方案3:替换类特性为System.Text.Json专用特性
将[DataContract]和[DataMember]替换为System.Text.Json的[JsonPropertyName]特性,统一前后端的命名规则:
// 移除[DataContract],改用JsonPropertyName public class AuthTokenResponse { [JsonPropertyName("access_token")] public string AccessToken { get; set; } [JsonPropertyName("token_type")] public string TokenType { get; set; } [JsonPropertyName("expires_in")] public string ExpiresSeconds { get; set; } public AuthTokenType AuthTokenType { get; set; } } public enum AuthTokenType { Generic, Custom }
这样后端会输出access_token等下划线命名的JSON键,客户端只要使用支持JsonPropertyName的反序列化器即可正确解析。
内容的提问来源于stack exchange,提问作者dros
相关产品推荐
相关产品推荐

