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

Blazor使用MudBlazor动态创建未知列数MudTable运行报错问题

解答

功能可行性

完全可以用MudBlazor实现你要的带排序、列顺序调整、筛选的动态表格,你现在的报错和实现问题,本质是没搞懂MudTable的渲染生命周期和模板的用法。

报错原因

你看到的空引用异常定位非常明确:

  • 组件第一次渲染的时候,ServerData的异步请求还没返回,rowTable.Items此时是null,你直接在HeaderContent里写rowTable.Items.ElementAt(0),必然触发空引用错误。
  • 你写的RowTemplate逻辑完全错误:RowTemplate是单条行数据的渲染模板,MudTable会自动遍历拿到的所有数据,逐行调用这个模板,根本不需要你自己写两层循环去遍历rowTable.Items,这么写不仅会重复渲染单元格,还会在数据未加载时触发空引用。

修正后的实现

不要从rowTable.Items里取列定义,单独维护一个动态列的集合,从首次请求返回的数据里初始化列,避免首次渲染的空值问题。

组件Razor代码

<MudTable ServerData="@GetEntityRowData" 
          @ref="rowTable" 
          Elevation="1" 
          Hover 
          Striped 
          Loading="@_isLoading"
          Sortable="true"
          ColumnReordering="true">
    <ToolBarContent>
        <MudTextField @bind-Value="_searchKeyword" 
                      Placeholder="输入关键词筛选" 
                      Adornment="Adornment.Start" 
                      AdornmentIcon="@Icons.Material.Filled.Search" 
                      Immediate="true" 
                      OnKeyUp="@(async () => await rowTable.ReloadServerData())" />
    </ToolBarContent>
    <HeaderContent>
        @foreach (var col in _dynamicColumns)
        {
            <MudTh SortLabel="@col.Key">@col.Key</MudTh>
        }
    </HeaderContent>
    <RowTemplate>
        @* context是MudTable自动注入的当前行数据实例,不需要自己遍历Items取值 *@
        @foreach (var col in _dynamicColumns)
        {
            <MudTd>@context.SourceRowJsonProperties[col.Key]</MudTd>
        }
    </RowTemplate>
    <NoRecordsContent>
        <MudText>No rows found</MudText>
    </NoRecordsContent>
    <LoadingContent>
        <MudText>Loading...</MudText>
    </LoadingContent>
    <PagerContent>
        <MudTablePager />
    </PagerContent>
</MudTable>

C#逻辑代码

@code {
    private MudTable<EntityRowDto>? rowTable;
    private List<KeyValuePair<string, object>> _dynamicColumns = new();
    private bool _isLoading;
    private string _searchKeyword = string.Empty;

    private async Task<TableData<EntityRowDto>> GetEntityRowData(TableState state)
    {
        _isLoading = true;
        try
        {
            // MudTable页码从0开始,直接+1就是接口需要的页码,不用单独判断0的情况
            var pageNumber = state.Page + 1;
            var sortField = state.SortLabel;
            var sortDir = state.SortDirection == SortDirection.Ascending ? "asc" : "desc";
            var url = $"api/entityrow?pageNumber={pageNumber}&pageSize={state.PageSize}&keyword={Uri.EscapeDataString(_searchKeyword)}&sortField={sortField}&sortDirection={sortDir}";

            var response = await Http.GetFromJsonAsync<PagedResponse<EntityRowDto>>(url);
            
            // 第一次拿到数据时初始化动态列
            if (response?.Items != null && response.Items.Any() && !_dynamicColumns.Any())
            {
                _dynamicColumns = response.Items.First().SourceRowJsonProperties.ToList();
            }

            return new TableData<EntityRowDto>
            {
                TotalItems = response?.Metadata.TotalItemCount ?? 0,
                Items = response?.Items ?? Enumerable.Empty<EntityRowDto>()
            };
        }
        finally
        {
            _isLoading = false;
        }
    }
}

MudTable数据访问说明

  • 行渲染时直接用RowTemplate里的context对象即可获取当前行数据,这是MudTable官方推荐的标准访问方式,不要通过@ref指向的表格实例去索引Items拿行数据。
  • 如果需要在表格外部访问当前加载的分页数据,可以等ServerData请求完成后再访问rowTable.Items,访问前一定要做判空处理,组件首次渲染阶段这个属性是null,不能直接调用Linq方法。
  • 排序、列拖拽调整、筛选功能MudTable都已经内置,只需要开启对应参数,把TableState里的分页、排序参数传给后端做对应的数据处理即可,不需要额外写前端交互逻辑。如果需要自定义筛选规则,在筛选输入变更后调用rowTable.ReloadServerData()就能触发表格重新请求数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:39:20