JSON数组反序列化报错求助:RuntimeBinderException问题排查
JSON反序列化错误排查与字段提取方案
问题描述
待反序列化的JSON结构:
{ "status": 200, "success": true, "message": "Success", "data": [ { "transaction_reference": "REF202301031128311645_1", "virtual_account_number": "1234567890", "principal_amount": "200.00", "settled_amount": "199.80", "fee_charged": "0.20", "transaction_date": "2023-01-03T00:00:00.000Z", "transaction_indicator": "C", "remarks": "Transfer FROM Transfer | [1234567] TO Merchant Name", "currency": "NGN", "alerted_merchant": false, "merchant_settlement_date": "2023-01-03T10:29:25.847Z", "frozen_transaction": null, "customer": { "customer_identifier": "1234567" } } ] }
需要提取的字段:status、transaction_reference、virtual_account_number、principal_amount、customer_identifier
尝试的代码:
string data = response.Content; string dataT = data.Replace("", string.Empty); dynamic stuff = JObject.Parse(dataT); dynamic status = stuff.status; var JsonResponse = stuff.data; var ResponseX = JsonNode.Parse(JsonResponse); // Deserializing json Array dynamic transaction_reference = ResponseX[0]["transaction_reference"]; dynamic virtual_account_number = ResponseX[1]["virtual_account_number"]; dynamic principal_amount = ResponseX[2]["principal_amount"]; dynamic customer = ResponseX[13]["customer_identifier"]; dynamic customer_identifier = customer.customer_identifier;
触发的错误:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
HResult=0x80131500
Message=The best overloaded method match for'System.Text.Json.Nodes.JsonNode.Parse(refSystem.Text.Json.Utf8JsonReader,System.Text.Json.Nodes.JsonNodeOptions?)' has some invalid arguments
Source=
StackTrace:
错误发生在var ResponseX = JsonNode.Parse(JsonResponse);行。
错误原因
- JSON库混用:同时使用Newtonsoft.Json(
JObject.Parse)和System.Text.Json(JsonNode.Parse),stuff.data是Newtonsoft的JArray类型,并非字符串,不符合JsonNode.Parse的参数要求(该方法仅接受字符串或Utf8JsonReader)。 - 数组索引逻辑错误:JSON的
data数组仅包含1个元素,代码中ResponseX[1]、ResponseX[2]、ResponseX[13]均为无效索引,且所有目标字段都在数组的第0个元素内部,并非按数组索引拆分字段。
正确提取方案
方案1:纯Newtonsoft.Json实现(适配现有代码)
string data = response.Content; // 无需空字符串替换,JObject.Parse可直接处理带空格的JSON dynamic stuff = JObject.Parse(data); // 提取status int status = stuff.status; // 处理data数组 var dataArray = stuff.data as JArray; if (dataArray != null && dataArray.Count > 0) { var firstItem = dataArray[0]; string transaction_reference = firstItem["transaction_reference"]?.ToString(); string virtual_account_number = firstItem["virtual_account_number"]?.ToString(); string principal_amount = firstItem["principal_amount"]?.ToString(); string customer_identifier = firstItem["customer"]["customer_identifier"]?.ToString(); // 后续业务逻辑处理 }
方案2:纯System.Text.Json实现
string data = response.Content; using var doc = JsonDocument.Parse(data); var root = doc.RootElement; // 提取status int status = root.GetProperty("status").GetInt32(); // 处理data数组 var dataArray = root.GetProperty("data"); if (dataArray.GetArrayLength() > 0) { var firstItem = dataArray[0]; string transaction_reference = firstItem.GetProperty("transaction_reference").GetString(); string virtual_account_number = firstItem.GetProperty("virtual_account_number").GetString(); string principal_amount = firstItem.GetProperty("principal_amount").GetString(); string customer_identifier = firstItem.GetProperty("customer").GetProperty("customer_identifier").GetString(); // 后续业务逻辑处理 }
方案3:强类型反序列化(最规范,避免运行时错误)
先定义对应实体类:
public class TransactionResponse { public int Status { get; set; } public bool Success { get; set; } public string Message { get; set; } public List<TransactionData> Data { get; set; } } public class TransactionData { public string Transaction_reference { get; set; } public string Virtual_account_number { get; set; } public string Principal_amount { get; set; } public Customer Customer { get; set; } } public class Customer { public string Customer_identifier { get; set; } }
再执行反序列化与字段提取:
string data = response.Content; // Newtonsoft.Json版本 var responseObj = JsonConvert.DeserializeObject<TransactionResponse>(data); // 或System.Text.Json版本 // var responseObj = JsonSerializer.Deserialize<TransactionResponse>(data); if (responseObj != null && responseObj.Data != null && responseObj.Data.Count > 0) { var firstTransaction = responseObj.Data[0]; int status = responseObj.Status; string transactionRef = firstTransaction.Transaction_reference; string virtualAccount = firstTransaction.Virtual_account_number; string principalAmount = firstTransaction.Principal_amount; string customerId = firstTransaction.Customer.Customer_identifier; // 后续业务逻辑处理 }
内容的提问来源于stack exchange,提问作者Emeka Okoye
相关产品推荐
相关产品推荐

