API返回动态货币对键时,C#解析空引用错误的解决方法
嘿,这个问题我太懂了!因为API返回的顶级键是随货币对动态变化的,固定的类结构根本适配不了,你遇到的“Object reference not set to an instance of object”错误,大概率是因为你尝试访问一个不存在的类属性(比如API返回USD_PKR,但你的类里只有PKR_PKR属性,那这个属性就是null,再访问它的val自然就报错了)。
给你几个实用的C#解决方案,任选其一就行:
方案1:使用Newtonsoft.Json的JObject解析(最灵活)
如果你已经在用Newtonsoft.Json(也就是Json.NET),直接用JObject来动态解析最方便:
using Newtonsoft.Json.Linq; // 假设apiResponse是你从API获取到的JSON字符串 string apiResponse = "{\"PKR_PKR\":{\"val\":1}}"; try { // 解析JSON为JObject JObject jsonObj = JObject.Parse(apiResponse); // 直接取第一个顶级属性的值(不管键名是什么) JToken currencyPairData = jsonObj.First.Value; // 提取val字段的值 decimal conversionValue = currencyPairData["val"].Value<decimal>(); // 赋值到文本框 yourTextBox.Text = conversionValue.ToString(); } catch (Exception ex) { // 处理异常,比如API返回格式错误、没有val字段等 yourTextBox.Text = $"获取失败:{ex.Message}"; }
方案2:用字典+实体类反序列化(类型更安全)
如果想保留类型安全,可以定义一个简单的实体类来对应val字段,然后把整个JSON反序列化为字典:
using Newtonsoft.Json; // 定义对应val的实体类 public class CurrencyConversionResult { public decimal val { get; set; } } // 解析代码 string apiResponse = "{\"PKR_PKR\":{\"val\":1}}"; try { // 反序列化为字典,键是动态的货币对,值是实体类 var conversionDict = JsonConvert.DeserializeObject<Dictionary<string, CurrencyConversionResult>>(apiResponse); // 检查字典是否有数据,然后取第一个值 if (conversionDict != null && conversionDict.Any()) { var result = conversionDict.Values.First(); yourTextBox.Text = result.val.ToString(); } else { yourTextBox.Text = "无转换数据"; } } catch (Exception ex) { yourTextBox.Text = $"获取失败:{ex.Message}"; }
方案3:使用System.Text.Json(.NET Core/5+原生支持)
如果用的是.NET Core或.NET 5及以上版本,直接用原生的System.Text.Json就行,不用额外装包:
using System.Text.Json; string apiResponse = "{\"PKR_PKR\":{\"val\":1}}"; try { using JsonDocument doc = JsonDocument.Parse(apiResponse); JsonElement root = doc.RootElement; // 检查根节点是对象且有属性 if (root.ValueKind == JsonValueKind.Object && root.EnumerateObject().Any()) { // 取第一个属性的值 JsonElement currencyPairData = root.EnumerateObject().First().Value; // 尝试获取val字段 if (currencyPairData.TryGetProperty("val", out JsonElement valElement) && valElement.ValueKind == JsonValueKind.Number) { yourTextBox.Text = valElement.GetDecimal().ToString(); } else { yourTextBox.Text = "未找到转换值"; } } else { yourTextBox.Text = "无效的响应数据"; } } catch (Exception ex) { yourTextBox.Text = $"获取失败:{ex.Message}"; }
关键提醒
一定要加异常处理和空值检查!比如API可能返回空字符串、格式错误的JSON,或者没有val字段,这些情况都可能导致报错,提前处理能让程序更健壮。
内容的提问来源于stack exchange,提问作者Alina Anjum
相关产品推荐
相关产品推荐

