Unity中嵌套类无法反序列化AWS Cognito Auth JSON请求
Unity中AWS Cognito登录响应JSON反序列化失败问题定位与解决
问题背景
在Unity中使用嵌套类反序列化AWS Cognito登录响应JSON时失败,尝试多种方法未解决,以下是相关响应内容、请求代码及解析类结构。
AWS Cognito登录响应JSON
{ "timestamp": "2024-05-17T02:14:10.331Z", "level": "INFO", "requestId": "2dc7b590-1827-4554-9821-908eb1d3ee3f", "message": { "$metadata": { "httpStatusCode": 200, "requestId": "0c684225-7a1b-469f-89e3-15d29da36f49", "attempts": 1, "totalRetryDelay": 0 }, "ChallengeName": "NEW_PASSWORD_REQUIRED", "ChallengeParameters": { "USER_ID_FOR_SRP": "348844c8-e001-7030-93c4-3c5a5a754fa2", "requiredAttributes": "[]", "userAttributes": "{\"email_verified\":\"true\",\"preferred_username\":\"RobloxHero\",\"email\":\"robloxhero@compassoftruth.org\"}" }, "Session": "AYABeHuZceyPXQVTVA1OPXwrdZIAHQABAAdTZXJ2aWNlABBDb2duaXRvVXNlclBvb2xzAAEAB2F3cy1rbXMAS2Fybjphd3M6a21zOnVzLWVhc3QtMTo3NDU2MjM0Njc1NTU6a2V5L2IxNTVhZmNhLWJmMjktNGVlZC1hZmQ4LWE5ZTA5MzY1M2RiZQC4AQIBAHjHL4WD3WpekpFe85nxP9Nwg99u3bPN6BTSaB-uHZcTLAF1FxlVsAaSp8ntnWxXieO7AAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMjuV5Bhw0j4lWg6JxAgEQgDusJsldE8RrnX72vgmOQkw9KkrzbARBsxGkfjRqS5A6T7T71F6umtOTz7XnjEqdeAfhfyQ2vT_Hmx2-nAIAAAAADAAAEAAAAAAAAAAAAAAAAABejP7rYrS09IQqwZHglO_k_____wAAAAEAAAAAAAAAAAAAAAEAAADVlPZSlzCXntBx_E8TEbzxbn4ZTZBEr5nMSXRinXYnmVRrlKjtLX7yv8giRh1z1_rYNSKGAY2b3cz1PyWadtwifpldG6_d3NdgthTaMpQNeIhJ_jmjfz0U_4hrYWVyz5OspPbR38Rlelj5r9DIQaGWGFMVVDuzeeouxbBTl83O3w5Rx2gYYZ3AmyIBrMiVxDscytZj8oJ4fit76lVlFlFNmwMywy6MjhDb80RGcYoUpkbUZn86X1Ycy5KZstb7tm4dFp7IN1ej69IcLmYZbvcJ4xBCZeEJCrfccFbdhVG0zGcPUB1lzw" } }
Unity登录请求代码
public void LoginRequest() { AWSUserLoginRequest request = new AWSUserLoginRequest(); request.username = username; request.password = password; using (UnityWebRequest www = UnityWebRequest.Post("https://game-api.compassoftruth.org/prod/Login", JsonUtility.ToJson(request), "application/json") ) { www.SendWebRequest(); while (www.isDone == false) { //do something, or nothing while blocking } if (www.result != UnityWebRequest.Result.Success) { Debug.Log(www.error); } else { LoginResult = JsonUtility.FromJson<AWSLoginResult>(www.downloadHandler.text.Replace('$'.ToString(), "")); // Show results as text Debug.Log(www.downloadHandler.text.Replace('$'.ToString(), "")); Debug.Log(LoginResult.level); } } }
调试得到的响应字符串
{"metadata":{"httpStatusCode":200,"requestId":"731de9a0-a3b3-4a75-a565-f19c49f19a50","attempts":1,"totalRetryDelay":0},"ChallengeName":"NEW_PASSWORD_REQUIRED","ChallengeParameters":{"USER_ID_FOR_SRP":"348844c8-e001-7030-93c4-3c5a5a754fa2","requiredAttributes":"[]","userAttributes":"{\"email_verified\":\"true\",\"preferred_username\":\"RobloxHero\",\"email\":\"robloxhero@compassoftruth.org\"}"},"Session":"AYABeJlFAr90U2rURQa1RoyPy-AAHQABAAdTZXJ2aWNlABBDb2duaXRvVXNlclBvb2xzAAEAB2F3cy1rbXMAS2Fybjphd3M6a21zOnVzLWVhc3QtMTo3NDU2MjM0Njc1NTU6a2V5L2IxNTVhZmNhLWJmMjktNGVlZC1hZmQ4LWE5ZTA5MzY1M2RiZQC4AQIBAHjHL4WD3WpekpFe85nxP9Nwg99u3bPN6BTSaB-uHZcTLAH4F1Ox2jph9NZcOwFtL6m-AAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM7FLUPDofg4S5f67nAgEQgDsIOeZuVErT75jsNRBJz63Pat7GgObkPeKx7Li_z5tvnDG4FvrbLoLjVcgJpVin-rz9Cp_bcfmxyjX0owIAAAAADAAAEAAAAAAAAAAAAAAAAAAtqnLZ5SIekFGUo3n6YKYi_____wAAAAEAAAAAAAAAAAAAAAEAAADV0iUMK4jkW4ioIy8AGcb5bLTQ3jW90JXuaucWAlImLuT55a3TaWyStOL_O6uJb-2NDqz7ejkQ3eUDlMn02AYwvj75cI4bB6nuaOSomjBZ4-tkT8AtpbykIYTgc451wjg5U9CrnbbTViMR-s3Fdx6P_rABop_INWkf1lAUs1xrlY5AMX3VGc2bjlHX9Ejips9irlVpnuUXic-AJXQUcZeHbi9DmcfSFe0VDTQGWMJmLFUZFWfJAQeo-dvQadfvkm2r1Lwwn42WGVkPykxbVqdkTUxIUcpFajlRAZp5B4PRxoJCBp-CVA"}
用于解析的嵌套类结构
using System; using UnityEngine; using UnityEngine.Tilemaps; using UnityEngine.Networking; using System.Collections; using System.Collections.Generic; using UnityEditor.VersionControl; [Serializable] public class AWSLoginResult { public string timestamp; public string level; public string requestId; public message message; } [Serializable] public class message { public string ChallangeName; public ChallangeParameters ChallangeParameters; public string Session; } [Serializable] public class ChallangeParameters { public string USER_ID_FOR_SRP; public string userAttributes; public string requiredAttributes; }
问题定位
- 结构不匹配:调试得到的响应是原JSON中
message字段的内容(无外层timestamp/level/requestId),但代码中仍用包含外层结构的AWSLoginResult反序列化,导致字段无法映射。 - 拼写错误:类中
ChallangeName/ChallangeParameters与JSON中的ChallengeName/ChallengeParameters拼写不一致(少一个字母e),导致字段无法绑定。 - 缺失字段定义:调试响应中的
metadata字段未在message类中定义,会丢失该部分数据(虽不影响核心字段,但不符合完整解析要求)。
解决方案
1. 修正类结构拼写与字段定义
using System; using UnityEngine; [Serializable] public class AWSLoginResult { public string timestamp; public string level; public string requestId; public Message message; } [Serializable] public class Message { public Metadata metadata; public string ChallengeName; public ChallengeParameters ChallengeParameters; public string Session; } [Serializable] public class Metadata { public int httpStatusCode; public string requestId; public int attempts; public int totalRetryDelay; } [Serializable] public class ChallengeParameters { public string USER_ID_FOR_SRP; public string userAttributes; public string requiredAttributes; }
2. 调整反序列化目标类
根据调试得到的响应结构,实际后端返回的是Message类对应的JSON,因此修改登录代码中的反序列化逻辑:
else { // 移除$字符,匹配类中的metadata字段 string cleanedJson = www.downloadHandler.text.Replace("$", ""); // 反序列化为Message类而非AWSLoginResult Message loginMessage = JsonUtility.FromJson<Message>(cleanedJson); Debug.Log(cleanedJson); // 打印正确的字段 Debug.Log(loginMessage.ChallengeName); }
3. 优化UnityWebRequest调用方式(可选)
避免用while循环阻塞主线程,改用协程实现异步请求:
public IEnumerator LoginRequest() { AWSUserLoginRequest request = new AWSUserLoginRequest(); request.username = username; request.password = password; using (UnityWebRequest www = UnityWebRequest.Post("https://game-api.compassoftruth.org/prod/Login", JsonUtility.ToJson(request), "application/json")) { yield return www.SendWebRequest(); if (www.result != UnityWebRequest.Result.Success) { Debug.Log(www.error); } else { string cleanedJson = www.downloadHandler.text.Replace("$", ""); Message loginMessage = JsonUtility.FromJson<Message>(cleanedJson); Debug.Log(cleanedJson); Debug.Log(loginMessage.ChallengeName); } } }
内容的提问来源于stack exchange,提问作者RobloxHero
相关产品推荐
相关产品推荐

