PAYATHON 2026

Blazor 从 .NET 9 升级到 .NET 10 后,ModalDialog 的 Message 为何变空?

数据小许

结论

从现有代码无法确认这是 .NET 10 引入的回归。应先检查 ModalDialog.Message 的来源,以及父组件重新渲染时传入的 ConfirmationMessage 是否仍有值。Message 是 [Parameter],由父组件提供。Show() 只调用 StateHasChanged,不会设置弹窗的可见状态,也不会保留或恢复消息内容。

检查参数在哪一步变空

Button 将 ConfirmationMessage 传给 ModalDialog:

<ModalDialog Message="@ConfirmationMessage" ...>
</ModalDialog>

先检查 Button 和 ModalDialog 的 OnParametersSet 中的消息值,再确认 ConfirmationMessage 是否由父组件提供,以及它会不会在点击或服务调用后被清空。父组件重渲染时,子组件参数会根据父组件当前状态重新设置。如果父组件此时传入空字符串,ModalDialog.Message 就会变空。

还要检查完整的 ModalDialog 实现。现有材料没有展示它如何控制显示,也没有展示 ConfirmationMessage 在哪里赋值。仅凭 Show() 中的 StateHasChanged,无法判断消息具体在哪一步丢失。

将消息参数与显示状态分开

建议由父组件持有消息内容,让 ModalDialog 用自己的状态控制显示。下面是示意写法,具体标记应根据现有弹窗实现调整:

@if (IsVisible)
{
    <div class="modal">
        <p>@Message</p>
        <!-- 弹窗按钮和其他内容 -->
    </div>
}
[Parameter]
public string Message { get; set; } = string.Empty;

private bool IsVisible;

public Task Show()
{
    IsVisible = true;
    return InvokeAsync(StateHasChanged);
}

public Task Hide()
{
    IsVisible = false;
    return InvokeAsync(StateHasChanged);
}

不要在 ModalDialog 内直接修改 [Parameter] Message。如果需要在子组件中编辑消息,可以将它复制到独立字段,再通过 EventCallback<string> 通知父组件更新。

检查事件回调和刷新

ShowCreateDialog 调用服务成功后会执行 ReloadData(),其中显式调用了 StateHasChanged。这会触发页面重新渲染,但单凭这一点无法说明消息为何变空。检查这条渲染路径上父组件传给 Button 的参数是否发生变化,也要确认组件是否因条件渲染而被移除后重新创建。

在 Blazor 组件事件回调中,框架通常会在回调完成后安排渲染。如果 ReloadData 只用于当前组件事件,显式调用 StateHasChanged 可能没有必要。若状态来自框架外部的回调,则可使用 InvokeAsync(StateHasChanged) 通知组件渲染。

示例中的 Show() 只请求重渲染,没有切换可见状态的逻辑。如果弹窗依赖组件库提供的打开 API,应确认调用了该 API;如果是自定义弹窗,则需要显式设置可见状态。

建议的定位顺序

  1. 检查父组件每次渲染时传入的 ConfirmationMessage 是否非空。
  2. 检查 ModalDialog.OnParametersSet 中的 Message,确认参数何时发生变化。
  3. 检查 Button 或 ModalDialog 是否因 @if 等条件被销毁并重新创建。
  4. 将弹窗可见状态与 Message 参数分开管理,再验证相同的操作路径。

现有信息不足以确定升级是否引入了特定框架变化,也无法据此给出适用于该项目的唯一修复方案。先根据参数值变化的位置,判断是父级数据被清空、组件实例被重建,还是弹窗的显示逻辑不完整。

备注:内容仅供参考。