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

Blazor WebAssembly中如何创建动态对象?解决items为空问题

你的问题出在System.Text.Json对dynamic的默认处理上——它不会返回一个真正的“动态对象”,而是返回JsonElement类型的实例。直接用dynamic声明变量时,调试器可能显示为空,但实际上数据是存在的,只是没法直接通过点语法访问。

下面提供三种可行的解决方案,无需为每个API单独创建实体类:

方案1:直接使用JsonElement(原生无依赖)

把dynamic替换成JsonElement,通过它的原生API访问JSON数据,这种方式不需要额外依赖,适合原生.NET场景:

protected override async Task OnInitializedAsync()
{
    string _baseURL = "";
    int caseSwitch = new Random().Next(1, 4);
    switch (caseSwitch)
    {
        case 1:
            _baseURL = "https://randomuser.me/api/";
            break;
        case 2:
            _baseURL = "https://reqres.in/api/users?page=2";
            break;
        default:
            _baseURL = "https://jsonplaceholder.typicode.com/todos";
            break;
    }
    // 替换dynamic为JsonElement
    JsonElement items = await Http.GetFromJsonAsync<JsonElement>(_baseURL);
    
    // 根据不同API结构访问数据
    if (_baseURL.Contains("randomuser"))
    {
        string firstName = items.GetProperty("results")[0].GetProperty("name").GetProperty("first").GetString();
    }
    else if (_baseURL.Contains("reqres"))
    {
        string email = items.GetProperty("data")[0].GetProperty("email").GetString();
    }
    else
    {
        string title = items[0].GetProperty("title").GetString();
    }
}

方案2:转为ExpandoObject(实现真正的动态属性访问)

通过手动反序列化将JSON转为ExpandoObject,可以像普通对象一样用点语法访问属性:

using System.Dynamic;
using System.Text.Json;

protected override async Task OnInitializedAsync()
{
    string _baseURL = "";
    int caseSwitch = new Random().Next(1, 4);
    switch (caseSwitch)
    {
        case 1:
            _baseURL = "https://randomuser.me/api/";
            break;
        case 2:
            _baseURL = "https://reqres.in/api/users?page=2";
            break;
        default:
            _baseURL = "https://jsonplaceholder.typicode.com/todos";
            break;
    }
    
    // 获取JSON字符串后手动反序列化为ExpandoObject
    string jsonString = await Http.GetStringAsync(_baseURL);
    dynamic items = JsonSerializer.Deserialize<ExpandoObject>(jsonString, new JsonSerializerOptions
    {
        PropertyNameCaseInsensitive = true // 忽略属性大小写,适配不同API的命名风格
    });
    
    // 直接用点语法访问属性
    if (_baseURL.Contains("randomuser"))
    {
        string firstName = items.results[0].name.first;
    }
    else if (_baseURL.Contains("reqres"))
    {
        string email = items.data[0].email;
    }
    else
    {
        string title = items[0].title;
    }
}

方案3:使用Newtonsoft.Json(Json.NET)

如果习惯了Newtonsoft对动态对象的友好支持,可以在项目中安装Newtonsoft.Json NuGet包,直接将JSON转为JObject/JArray:

using Newtonsoft.Json.Linq;

protected override async Task OnInitializedAsync()
{
    string _baseURL = "";
    int caseSwitch = new Random().Next(1, 4);
    switch (caseSwitch)
    {
        case 1:
            _baseURL = "https://randomuser.me/api/";
            break;
        case 2:
            _baseURL = "https://reqres.in/api/users?page=2";
            break;
        default:
            _baseURL = "https://jsonplaceholder.typicode.com/todos";
            break;
    }
    
    string jsonString = await Http.GetStringAsync(_baseURL);
    // 单个对象用JObject.Parse,数组用JArray.Parse
    dynamic items = _baseURL.Contains("todos") ? JArray.Parse(jsonString) : JObject.Parse(jsonString);
    
    // 直接点语法访问属性
    if (_baseURL.Contains("randomuser"))
    {
        string firstName = items.results[0].name.first;
    }
    else if (_baseURL.Contains("reqres"))
    {
        string email = items.data[0].email;
    }
    else
    {
        string title = items[0].title;
    }
}

三种方案各有侧重:方案1最轻量化,方案2适合需要原生动态属性访问的场景,方案3适合熟悉Newtonsoft生态的开发者,你可以根据需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:01:12