Newtonsoft.Json.JsonReaderException异常:无法反序列化获取Product对象求助
解决Newtonsoft.Json.JsonReaderException异常及Product反序列化问题
异常信息
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: S. Path '', line 0, position 0.'
错误原因分析
- GET请求错误添加请求体:GET请求无需设置
Content,你添加的StringContent会导致服务器识别请求格式错误,返回非JSON响应(比如错误提示文本,开头为"S",对应异常中的字符提示)。 - 错误获取响应内容:
response.Result.ToString()获取的是HttpResponseMessage对象的描述字符串,并非接口返回的JSON数据,这直接导致反序列化失败。 - 反序列化类型不匹配:接口返回的JSON是多层嵌套结构,直接反序列化为
Product[]完全不符合数据结构。
修正方案及代码
1. 修正后的请求与反序列化代码
public async Task<List<Product>> ListAsync() { var retorno = new List<Product>(); try { using (var client = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Get, "https://teste.teste1.com.br/app/Api/V1/Products/list"); // 配置请求头 client.DefaultRequestHeaders.Add("x-user-email", "victor@manairadigital.com.br"); client.DefaultRequestHeaders.Add("x-api-key", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb2Rfc3RvcmUiOjMsImNvZF9jb21wYW55Ijo3fQ.E_sxhnwcmN5GtNGRYbVD66ciMi3JoJNjormS1q3mxYg"); client.DefaultRequestHeaders.Add("x-store-key", "3"); client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); var response = await client.SendAsync(request); // 确保请求成功,非2xx状态码直接抛出异常 response.EnsureSuccessStatusCode(); // 读取实际的JSON响应体 var jsonString = await response.Content.ReadAsStringAsync(); var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(jsonString); // 提取嵌套的Product对象列表 retorno = apiResponse.Result.Data.Select(item => item.Product).ToList(); } } catch (Exception ex) { // 可添加日志记录后再抛出 throw; } return retorno; }
2. 匹配JSON结构的模型类
必须定义与返回JSON完全匹配的嵌套模型,才能正确反序列化:
public class ApiResponse { public bool Success { get; set; } public int Offset { get; set; } public ResultData Result { get; set; } } public class ResultData { public bool Error { get; set; } public int Registers_count { get; set; } public int Pages_count { get; set; } public int Page { get; set; } public List<ProductWrapper> Data { get; set; } } public class ProductWrapper { public Product Product { get; set; } } public class Product { public string Sku { get; set; } public string Name { get; set; } public string Description { get; set; } public string Status { get; set; } public int Qty { get; set; } public decimal Price { get; set; } public decimal? List_price { get; set; } public decimal Weight_gross { get; set; } public decimal Weight_liquid { get; set; } public int Height { get; set; } public int Width { get; set; } public int Length { get; set; } public string Items_per_package { get; set; } public string Brand { get; set; } public string Ean { get; set; } public string Ncm { get; set; } public List<Category> Categories { get; set; } public List<string> Variation_attributes { get; set; } public List<Variation> Variations { get; set; } public List<string> Images { get; set; } public Dictionary<string, string> Published_marketplace { get; set; } public List<MarketplaceLink> Marketplace_offer_links { get; set; } } public class Category { public string Code { get; set; } public string Name { get; set; } } public class Variation { public string Sku { get; set; } public int Qty { get; set; } public string EAN { get; set; } public decimal Price { get; set; } public decimal List_price { get; set; } public List<string> Images { get; set; } public List<Variant> Variant { get; set; } } public class Variant { public string Size { get; set; } public string Color { get; set; } } public class MarketplaceLink { public string Name { get; set; } public string Href { get; set; } }
补充说明
- 改用
async/await是.NET异步编程的规范写法,避免Wait()导致的线程阻塞问题。 - 若需要保持同步方法,可将
await替换为.Result,但不推荐在生产环境使用。 - 模型类属性名需与JSON键严格匹配,若要使用C#驼峰命名,可添加
[JsonProperty("键名")]特性映射。
内容的提问来源于stack exchange,提问作者VICTOR MARCONI SANTOS DE OLIVE
相关产品推荐
相关产品推荐

