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
相关产品推荐
相关产品推荐

