C#中API GET数据无法正确映射至PUT请求的问题求助
我在C#中实现从API获取数据并复用部分字段发起PUT请求的功能时遇到异常:仅titleId能正确更新,imageUrl、playerName、allianceId、rankId未从GET返回结果中取值,honor和prestige使用了模型默认值。以下是相关日志与代码,求排查方向:
日志信息
2023-06-24 00:10:29.270 +00:00 [INF] Response received for /api/MemberDetail/"c4566a7e-fe3d-46e4-abbe-c34d2fc097ce":
{ "memberId":"c4566a7e-fe3d-46e4-abbe-c34d2fc097ce", "imageUrl":"https://dev.xcl.one/Players/a9d17140-2a6b-465d-bcfb-a13770c03eda.jpg", "playerName":"FLU", "allianceId":"47f2cbcc-91e8-4d3a-ae95-27b2a3782bc1", "titleId":"3ccbba59-85fb-491e-92e6-f17f2584776b", "rankId":"bdbfe6e6-b515-42d3-b9c8-9dbba42fd06f", "honor":0, "prestige":100, "dateTimeUtc":"2023-06-23T18:35:59.7925881" }
2023-06-24 00:10:29.287 +00:00 [INF] Sending PUT request with content:
{ "memberId":"c4566a7e-fe3d-46e4-abbe-c34d2fc097ce", "titleId":"2902c1c0-0fba-4b04-908c-2c2aa7183c82", "imageUrl":"", "playerName":"", "allianceId":"00000000-0000-0000-0000-000000000000", "rankId":"00000000-0000-0000-0000-000000000000", "honor":0, "prestige":100, "dateTimeUtc":"2023-06-24T00:10:29.2785496Z" }
问题代码
var getResponse = await client.GetAsync($"/api/MemberDetail/{passedMemberId}"); //_logger.LogInformation("GET request sent to /api/MemberDetail/{passedMemberId}", passedMemberId); if (getResponse.IsSuccessStatusCode) { var responseContent = await getResponse.Content.ReadAsStringAsync(); _logger.LogInformation("Response received for /api/MemberDetail/{passedMemberId}: {responseContent}", passedMemberId, responseContent); if (!string.IsNullOrEmpty(responseContent)) { var memberApiDetail = JsonSerializer.Deserialize<MemberDetail>(responseContent); if (memberApiDetail != null) { var promotionPayload = new { memberId = passedMemberId, titleId = passedTitleId, imageUrl = memberApiDetail.ImageUrl, playerName = memberApiDetail.PlayerName, allianceId = memberApiDetail.AllianceId, rankId = memberApiDetail.RankId, honor = memberApiDetail.Honor != 0 ? memberApiDetail.Honor : 0, prestige = memberApiDetail.Prestige != 100 ? memberApiDetail.Prestige : 100, dateTimeUtc = memberApiDetail.DateTimeUtc }; var promotionPayloadString = JsonSerializer.Serialize(promotionPayload); var putContent = new StringContent(promotionPayloadString, Encoding.UTF8, "application/json"); _logger.LogInformation("Sending PUT request with content: {content}", promotionPayloadString); var response = await client.PutAsync($"/api/MemberDetail/{passedMemberId}", putContent); if (response.IsSuccessStatusCode) { //_logger.LogInformation("Promotion successfully updated for memberId: {memberId}", passedMemberId); } } } } ... public class MemberDetail { //public Guid Id { get; set; } [Key] public Guid MemberId { get; set; } public string ImageUrl { get; set; } = string.Empty; public string PlayerName { get; set; } = string.Empty; public Guid AllianceId { get; set; } = Guid.Empty; public Guid TitleId { get; set; } = Guid.Empty; public Guid RankId { get; set; } = Guid.Empty; public int Honor { get; set; } = 0; public long Prestige { get; set; } = 100; public DateTime DateTimeUtc { get; set; } = DateTime.UtcNow; }
排查方向
修复JSON反序列化大小写不匹配问题:
MemberDetail类属性是大驼峰格式(如ImageUrl),但API返回的JSON字段是小驼峰(如imageUrl),默认System.Text.Json不会自动映射大小写,导致反序列化时这些字段无法被赋值,只能用类的默认值。解决方法是添加反序列化配置:var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var memberApiDetail = JsonSerializer.Deserialize<MemberDetail>(responseContent, options);移除冗余的字段判断逻辑:
honor和prestige的三元判断完全多余,比如memberApiDetail.Honor != 0 ? memberApiDetail.Honor : 0,因为Honor默认值就是0,API返回值也是0,直接使用memberApiDetail.Honor和memberApiDetail.Prestige即可,避免逻辑冗余。验证反序列化结果:
在反序列化后添加日志输出memberApiDetail的所有属性值,确认是否确实从API获取到数据:_logger.LogInformation("Deserialized data: ImageUrl={0}, PlayerName={1}, AllianceId={2}", memberApiDetail.ImageUrl, memberApiDetail.PlayerName, memberApiDetail.AllianceId);以此确认是反序列化环节的问题,还是构建
promotionPayload时的问题。
内容的提问来源于stack exchange,提问作者AlwaysResearching

