You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Blazor服务端如何正确反序列化指定结构JSON数组

C# Blazor服务端反序列化JSON数组空引用问题

问题描述

我在服务端C# Blazor项目中尝试反序列化如下JSON数组:

[
    {
        "buy": {
            "forQuery": {
                "bid": true,
                "types": [
                    16265
                ],
                "regions": [
                    10000002
                ],
                "systems": [
                    30000142
                ],
                "hours": 24,
                "minq": 1
            },
            "volume": 12177,
            "wavg": 118125.12,
            "avg": 118260.00,
            "variance": 58000.00,
            "stdDev": 240.83,
            "median": 118100.00,
            "fivePercent": 118466.60,
            "max": 118600.00,
            "min": 118000.00,
            "highToLow": true,
            "generated": 1655337615423
        },
        "sell": {
            "forQuery": {
                "bid": false,
                "types": [
                    16265
                ],
                "regions": [
                    10000002
                ],
                "systems": [
                    30000142
                ],
                "hours": 24,
                "minq": 1
            },
            "volume": 935,
            "wavg": 178386.31,
            "avg": 194183.33,
            "variance": 3731725666.67,
            "stdDev": 61087.85,
            "median": 140350.00,
            "fivePercent": 134900.00,
            "max": 250000.00,
            "min": 134900.00,
            "highToLow": false,
            "generated": 1655337615423
        }
    }
]

源API地址:EVE Marketer市场数据接口

我只需要提取以下字段:

  • buy节点下的min、max值
  • sell节点下的min、max值

目前已定义映射类如下:

public class BuySellStat
{
    public double max;
    public double min;
}

public class EveMarketerResponse
{
    public BuySellStat Buy;
    public BuySellStat Sell;        
}

尝试过反序列化为Dictionary、List、Array等多种类型,始终反序列化失败。

问题复现

失败场景

使用HttpClient.GetFromJsonAsync反序列化时,遍历结果抛出NullReferenceException:

var list = HttpClient.GetFromJsonAsync<List<EveMarketerResponse>>("https://api.evemarketer.com/ec/marketstat/json?typeid=16265&usesystem=30000142").Result;
        
await JsConsoleLogger.LogAsync(list.Count.ToString()); // 浏览器控制台可正常输出list长度
foreach (var response in list)
{
    await JsConsoleLogger.LogAsync(response.Buy.min.ToString()); // 此处抛出空引用异常
    await JsConsoleLogger.LogAsync(response.Buy.max.ToString());
    await JsConsoleLogger.LogAsync(response.Sell.min.ToString());
    await JsConsoleLogger.LogAsync(response.Sell.min.ToString());
}

改用await异步调用GetFromJsonAsync仍然出现相同问题。

正常运行场景

先获取字符串再用Newtonsoft.Json反序列化可以正常运行:

var responseJson = await HttpClient.GetStringAsync("https://api.evemarketer.com/ec/marketstat/json?typeid=16265&usesystem=30000142");
var responseList = JsonConvert.DeserializeObject<List<EveMarketerResponse>>(responseJson);

foreach (var response in responseList)
{
    await JsConsoleLogger.LogAsync("buy min" + response.Buy.min.ToString());
    await JsConsoleLogger.LogAsync("buy max" + response.Buy.max.ToString());
    await JsConsoleLogger.LogAsync("sell min" + response.Sell.min.ToString());
    await JsConsoleLogger.LogAsync("sell max" + response.Sell.max.ToString());
}

问题原因

两种反序列化方式表现不一致的核心原因是默认匹配规则不同:

  • GetFromJsonAsync默认使用System.Text.Json序列化器,该序列化器默认严格区分字段/属性名大小写。接口返回的JSON字段为全小写的buy/sell/min/max,和C#类中定义的大写开头Buy/Sell无法匹配,因此反序列化后Buy、Sell属性为null,访问时抛出空引用异常。
  • JsonConvert.DeserializeObject是Newtonsoft.Json的方法,该序列化器默认不区分大小写匹配字段名,因此可以正常映射。

解决方案

方案1:配置System.Text.Json大小写不敏感(无需修改现有类,推荐)

调用GetFromJsonAsync时传入序列化配置,开启大小写不敏感匹配即可:

var jsonOptions = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
var list = await HttpClient.GetFromJsonAsync<List<EveMarketerResponse>>(
    "https://api.evemarketer.com/ec/marketstat/json?typeid=16265&usesystem=30000142", 
    jsonOptions);

如果需要全局生效,可以在Program.cs中配置默认Json序列化选项,避免每次调用重复传参。

方案2:显式指定字段映射关系

给类的成员添加特性,显式声明对应JSON的字段名,不受序列化器默认大小写规则影响:

// 若使用System.Text.Json,引入using System.Text.Json.Serialization;
public class BuySellStat
{
    [JsonPropertyName("max")]
    public double max;
    [JsonPropertyName("min")]
    public double min;
}

public class EveMarketerResponse
{
    [JsonPropertyName("buy")]
    public BuySellStat Buy;
    [JsonPropertyName("sell")]
    public BuySellStat Sell;        
}

如果使用Newtonsoft.Json,将[JsonPropertyName]替换为[JsonProperty]特性即可。


内容的提问来源于stack exchange,提问作者soomon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 02:33:44