如何在C#中反序列化JSON数组?RestSharp调用API遇序列化异常
First, let's break down why you're hitting that exception: your current JsonObjects class expects a List<GetValues> for the Values property, but when the API returns a string array (like {"Fields": ["Value.temp"]}), Newtonsoft.Json can't convert a plain string into your GetValues object—hence the Could not cast or convert from System.String to Namespace.GetValues error.
Since you need to handle multiple distinct JSON response structures, here are the most practical solutions:
1. Use Strongly-Typed Classes for Each Response Structure (Recommended)
This is the best approach for type safety, maintainability, and compile-time checks. Create separate classes that match each API's response format:
Example Classes for Your Response Types
// For {"Fields": ["Temp1.Value", "Temp2.Value", ...]} public class FieldsResponse { public List<string> Fields { get; set; } } // For {"Errors": [{"ErrorCode": "...", ...}], "ValueErrors": []} public class ErrorDetail { public string ErrorCode { get; set; } public string Message { get; set; } public string TempName { get; set; } } public class ErrorResponse { public List<ErrorDetail> Errors { get; set; } public List<object> ValueErrors { get; set; } // Use object if ValueErrors can have mixed types } // For {"Total": 1, "Categories": [{"Id": "...", "Name": "..."}]} public class Category { public string Id { get; set; } public string Name { get; set; } } public class CategoryResponse { public int Total { get; set; } public List<Category> Categories { get; set; } }
Usage in Your RestSharp Call
After getting the response content, deserialize into the appropriate class based on which API you're calling:
IRestResponse restResponse = clientRest.Execute(restRequest); string content = restResponse.Content; // If calling the API that returns Fields var fieldsResult = JsonConvert.DeserializeObject<FieldsResponse>(content); List<string> fields = fieldsResult.Fields; // If calling the error API var errorResult = JsonConvert.DeserializeObject<ErrorResponse>(content); List<ErrorDetail> errors = errorResult.Errors; // If calling the categories API var categoryResult = JsonConvert.DeserializeObject<CategoryResponse>(content); List<Category> categories = categoryResult.Categories;
2. Use JObject for Dynamic Parsing (For Highly Variable Responses)
If you need to handle unpredictable response structures, use Newtonsoft.Json's JObject to parse the content dynamically:
JObject responseJson = JObject.Parse(content); // Check which key exists to determine the response type if (responseJson.ContainsKey("Fields")) { List<string> fields = responseJson["Fields"].ToObject<List<string>>(); // Process fields } else if (responseJson.ContainsKey("Errors")) { List<ErrorDetail> errors = responseJson["Errors"].ToObject<List<ErrorDetail>>(); // Process errors } else if (responseJson.ContainsKey("Categories")) { List<Category> categories = responseJson["Categories"].ToObject<List<Category>>(); // Process categories }
3. Custom JsonConverter (For Edge Cases)
If you have a scenario where the same endpoint returns mixed array types (unlikely in well-designed APIs), you could create a custom JsonConverter to handle both string arrays and object arrays. However, this adds complexity and is usually unnecessary if you can use the first two approaches.
Why Your Original Code Failed
Your JsonObjects class defines Values as List<GetValues>, which expects an array of objects (each with a Values string property). But when the API returns ["Value.temp"], it's an array of strings—not objects. Newtonsoft.Json can't automatically map a string to your GetValues class, causing the serialization exception.
内容的提问来源于stack exchange,提问作者user12474845

