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;如果是自定义弹窗,则需要显式设置可见状态。
建议的定位顺序
- 检查父组件每次渲染时传入的
ConfirmationMessage是否非空。 - 检查
ModalDialog.OnParametersSet中的Message,确认参数何时发生变化。 - 检查
Button或ModalDialog是否因@if等条件被销毁并重新创建。 - 将弹窗可见状态与
Message参数分开管理,再验证相同的操作路径。
现有信息不足以确定升级是否引入了特定框架变化,也无法据此给出适用于该项目的唯一修复方案。先根据参数值变化的位置,判断是父级数据被清空、组件实例被重建,还是弹窗的显示逻辑不完整。
备注:内容仅供参考。
