在Blazor WebAssembly ASP.NET Core托管项目中,如何传递服务器端填充的DataTable至客户端?
把服务器端DataTable传递到Blazor WebAssembly客户端的实现方案
一、服务器端改造
DataTable包含大量元数据,直接序列化传输会出现兼容性问题,因此需要先将其转换为可序列化的轻量格式,再通过API接口暴露给客户端。
1. 转换DataTable为可序列化数据
推荐使用**强类型DTO(数据传输对象)**封装数据,兼顾类型安全和可维护性:
// 定义与数据库表字段匹配的DTO类 public class DictionaryItem { public int Id { get; set; } // 替换为你表中的实际字段 public string DictKey { get; set; } public string DictValue { get; set; } // 其他字段按需添加 } // 在ClssDictionary类中新增转换方法 public static List<DictionaryItem> ConvertToDtoList() { return DtDictionary.AsEnumerable() .Select(row => new DictionaryItem { Id = row.Field<int>("Id"), // 字段名对应数据库表列名 DictKey = row.Field<string>("DictKey"), DictValue = row.Field<string>("DictValue") }).ToList(); }
如果不想定义强类型,也可以转为通用字典列表(灵活性高但类型不安全):
public static List<Dictionary<string, object>> ConvertToDictList() { var dataList = new List<Dictionary<string, object>>(); foreach (DataRow row in DtDictionary.Rows) { var rowDict = new Dictionary<string, object>(); foreach (DataColumn col in DtDictionary.Columns) { rowDict[col.ColumnName] = row[col]; } dataList.Add(rowDict); } return dataList; }
2. 创建API端点暴露数据
添加API控制器,提供HTTP接口返回转换后的数据:
[ApiController] [Route("api/dictionary")] public class DictionaryController : ControllerBase { [HttpGet] public IActionResult GetDictionaryData() { // 确保DtDictionary已被填充(可在项目启动时调用M2dDictionary) var dtoList = ClssDictionary.ConvertToDtoList(); return Ok(dtoList); } }
3. 启动时预加载数据
在服务器的Program.cs中,启动阶段调用M2dDictionary填充DataTable:
var app = builder.Build(); // 预加载字典数据 await ClssDictionary.M2dDictionary(); // 其他中间件配置 app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
二、Blazor WebAssembly客户端实现
1. 定义客户端DTO类
在客户端项目中创建与服务器端一致的DictionaryItem类:
public class DictionaryItem { public int Id { get; set; } public string DictKey { get; set; } public string DictValue { get; set; } }
2. 创建数据服务调用API
添加服务类封装HTTP请求逻辑:
public class DictionaryService { private readonly HttpClient _httpClient; public DictionaryService(HttpClient httpClient) { _httpClient = httpClient; } public async Task<List<DictionaryItem>> GetDictionaryAsync() { try { return await _httpClient.GetFromJsonAsync<List<DictionaryItem>>("api/dictionary"); } catch (Exception ex) { // 处理请求异常,如日志记录或用户提示 Console.WriteLine($"获取字典数据失败:{ex.Message}"); return new List<DictionaryItem>(); } } }
3. 注册服务并在组件中使用
在客户端Program.cs注册服务:
builder.Services.AddScoped<DictionaryService>();
在Blazor组件中调用服务获取并展示数据:
@inject DictionaryService DictService @if (_dictionaryItems == null) { <p>加载中...</p> } else { <table class="table"> <thead> <tr> <th>ID</th> <th>键</th> <th>值</th> </tr> </thead> <tbody> @foreach (var item in _dictionaryItems) { <tr> <td>@item.Id</td> <td>@item.DictKey</td> <td>@item.DictValue</td> </tr> } </tbody> </table> } @code { private List<DictionaryItem> _dictionaryItems; protected override async Task OnInitializedAsync() { _dictionaryItems = await DictService.GetDictionaryAsync(); } }
三、关键注意事项
- CORS配置:若客户端与服务器不在同一域名下,需在服务器
Program.cs中配置CORS允许客户端访问:builder.Services.AddCors(options => { options.AddPolicy("AllowBlazorClient", policy => { policy.WithOrigins("https://your-blazor-client-url") .AllowAnyHeader() .AllowAnyMethod(); }); }); // 启用CORS中间件 app.UseCors("AllowBlazorClient"); - 异常处理:API和客户端都要添加异常捕获逻辑,避免无提示崩溃。
- 数据缓存:若字典数据不频繁更新,可在客户端或服务器端添加缓存,减少重复请求。
内容的提问来源于stack exchange,提问作者Razel Marquez Bigayan
相关产品推荐
相关产品推荐

