在C#控制台程序中枚举未知JSON属性(Json.Net/DalSoft.RestClient)
Hey there! Let's break down why you're hitting that System.AggregateException (with an inner RuntimeBinderException: Cannot perform runtime binding on a null reference) when trying to enumerate unknown JSON properties from the http://jsonplaceholder.typicode.com/users endpoint, and fix it.
What's Causing the Issue?
Chances are, you're using DalSoft.RestClient's dynamic return type, and one of these is happening:
- You're trying to access a property that doesn't exist on the dynamic object
- The response failed to parse correctly (or returned null) and you're attempting to bind to a null reference
- You're using
.Resultinstead ofawaiton the async call, which wraps any inner exceptions in anAggregateException
Solution 1: Use Newtonsoft.Json Directly (Best for Unknown JSON Structures)
Newtonsoft.Json's JObject and JArray are built specifically for handling dynamic/unknown JSON. They let you safely enumerate all properties without runtime binding errors.
First, make sure you have the Newtonsoft.Json NuGet package installed:
Install-Package Newtonsoft.Json
Then use this code to fetch and parse the response reliably:
using System; using System.Net.Http; using Newtonsoft.Json.Linq; class Program { static async System.Threading.Tasks.Task Main(string[] args) { using var httpClient = new HttpClient(); try { // Fetch the raw JSON response string jsonResponse = await httpClient.GetStringAsync("http://jsonplaceholder.typicode.com/users"); // Parse into a JArray since the API returns an array of user objects JArray usersArray = JArray.Parse(jsonResponse); // Iterate over each user and enumerate all properties foreach (JObject user in usersArray) { Console.WriteLine("--- User Properties ---"); foreach (var property in user.Properties()) { Console.WriteLine($"{property.Name}: {property.Value}"); } Console.WriteLine(); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); if (ex.InnerException != null) Console.WriteLine($"Inner Error: {ex.InnerException.Message}"); } } }
This works because JObject.Properties() explicitly enumerates every existing property in the JSON object—no guesswork, no null reference binding failures.
Solution 2: Adjust DalSoft.RestClient Usage
If you want to stick with DalSoft.RestClient, avoid dynamic types and instead parse the response into a JArray/JObject to safely enumerate properties. Also, always use await instead of .Result to skip the AggregateException wrapping.
First, ensure you have both required packages installed:
Install-Package DalSoft.RestClient Install-Package Newtonsoft.Json
Here's the adjusted code:
using System; using DalSoft.RestClient; using Newtonsoft.Json.Linq; class Program { static async System.Threading.Tasks.Task Main(string[] args) { try { var client = new RestClient("http://jsonplaceholder.typicode.com"); // Get the response as a JArray instead of dynamic to avoid runtime binding issues JArray usersArray = await client.Resource("users").GetAsync<JArray>(); foreach (JObject user in usersArray) { Console.WriteLine("--- User Properties ---"); foreach (var property in user.Properties()) { Console.WriteLine($"{property.Name}: {property.Value}"); } Console.WriteLine(); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); if (ex.InnerException != null) Console.WriteLine($"Inner Error: {ex.InnerException.Message}"); } } }
Key Takeaways to Avoid This Issue Again:
- Always use
awaitfor async calls: This bypassesAggregateExceptionand gives you direct access to the actual error for easier debugging. - Skip dynamic types for unknown JSON: Dynamic relies on runtime binding, which fails hard when properties are missing or references are null.
JObject/JArrayare purpose-built for this scenario. - Explicitly enumerate properties: Using
JObject.Properties()ensures you only access existing properties, eliminating null reference binding errors entirely.
内容的提问来源于stack exchange,提问作者Joe Johnston

