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

ASP.NET Blazor .NET 7编辑/添加行时模态框不显示问题排查

Blazor .NET Core 7 模态框点击不显示问题排查与修复

问题描述

基于ASP.NET Blazor .NET Core 7开发,点击表格编辑按钮时,Bootstrap模态框无法正常显示。已在ServersNames.razor组件中编写模态框代码,但点击按钮后弹窗无任何响应。

相关代码

ServersNames.razor组件

@page "/Servers/ServersNames"
@using UC.AppRepository.Core.Entities
@using UC.AppRepository.Core;
@using UC.AppRepository.UI;
@using System.Text.Json
@using System.Text.Json.Serialization
@inject IHttpClientFactory ClientFactory
@inject Microsoft.Extensions.Configuration.IConfiguration config
@inject IJSRuntime JS
@using System.IO
@using BlazorInputFile

<table class="class table-striped">
    <thead>
        <tr>
            <th>ServerId</th>
            <th>Server Name</th>
            <th>Server Type</th>
            <th>Options</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var serv in ServerName)
        {
            <tr>
                <td>@serv.serverID</td>
                <td>@serv.server_Name</td>
                <td>@serv.server_Type</td>
                <td>
                    <button type="button" class="btn btn-light mr-1" data-bs-toggle="modal" data-bs-target="#exampleModal" @onclick="(()=> editClick(serv))">
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">
                            <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
                        </svg>
                    </button>
                </td>
            </tr>
        }
    </tbody>
</table>

<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">
                    @ModalTitle
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </h5>
            </div>
            <div class="modal-body">
                <div class="input-group mb-3">
                    <span class="input-group-text">Server Name</span>
                    <input type="text" class="form-control" @bind="server_Name" />

                    <span class="input-group-text">Server Type</span>
                    <input type="text" class="form-control" @bind="server_Type" />

                    @if (ModalTitle == "Add Server")
                    {
                        <button type="button" class="btn btn-primary" @onclick="CreateClick">Create</button>
                    }
                    else
                    {
                        <button type="button" class="btn btn-primary" @onclick="UpdateClick">Update</button>
                    }
                </div>
            </div>
        </div>
    </div>
</div>

后端逻辑代码

@code
{
    public class ServerNamesClass
    {
        public int serverID { get; set; }
        public string server_Name { get; set; }
        public string server_Type { get; set; }
    }

    private IEnumerable<ServerNamesClass> ServerName = Array.Empty<ServerNamesClass>();

    private string ModalTitle;
    private int serverID;
    private string server_Name;
    public string server_Type;

    protected override async Task OnInitializedAsync()
    {
        await RefreshList();
    }

    private async Task RefreshList()
    {
        var request = new HttpRequestMessage(HttpMethod.Get, config["API_URL"] + "ServerNames");
        var client = ClientFactory.CreateClient();
        var response = await client.SendAsync(request);
        using var responsestream = await response.Content.ReadAsStreamAsync();
        ServerName = await JsonSerializer.DeserializeAsync<IEnumerable<ServerNamesClass>>(responsestream);
    }

    private void editClick(ServerNamesClass serv)
    {
        ModalTitle = "Edit Server";
        serverID = serv.serverID;
        server_Name = serv.server_Name;
        server_Type = serv.server_Type;
    }

    private void AddClick()
    {
        ModalTitle = "Add Server";
        serverID = 0;
        server_Name = "";
        server_Type = "";
    }
}

问题原因

  1. 事件冲突:按钮同时使用了Bootstrap原生属性data-bs-toggle/data-bs-target和Blazor的@onclick事件。Blazor的事件处理默认会阻止原生DOM事件的冒泡和默认行为,导致Bootstrap触发模态框的逻辑无法执行。
  2. 状态更新时机:即使原生事件能触发,editClick方法更新组件状态后,Blazor需要异步完成渲染,此时模态框可能已经显示,但内容还是旧值,出现数据不同步的问题。

修复方案

方案一:通过IJSRuntime手动控制模态框(推荐)

移除Bootstrap原生触发属性,在Blazor状态更新完成后,调用Bootstrap的JS API显示模态框。

  1. 修改按钮代码:去掉data-bs-toggle和data-bs-target,只保留@onclick:
<button type="button" class="btn btn-light mr-1" @onclick="(()=> editClick(serv))">
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">
        <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
    </svg>
</button>
  1. 修改editClick和AddClick方法:更新状态后,调用JS显示模态框:
private async Task editClick(ServerNamesClass serv)
{
    ModalTitle = "Edit Server";
    serverID = serv.serverID;
    server_Name = serv.server_Name;
    server_Type = serv.server_Type;
    // 等待Blazor完成状态渲染
    await Task.Delay(10);
    // 调用Bootstrap API显示模态框
    var modalInstance = await JS.InvokeAsync<IJSObjectReference>("bootstrap.Modal.getOrCreateInstance", "#exampleModal");
    await modalInstance.InvokeVoidAsync("show");
}

private async Task AddClick()
{
    ModalTitle = "Add Server";
    serverID = 0;
    server_Name = "";
    server_Type = "";
    await Task.Delay(10);
    var modalInstance = await JS.InvokeAsync<IJSObjectReference>("bootstrap.Modal.getOrCreateInstance", "#exampleModal");
    await modalInstance.InvokeVoidAsync("show");
}

方案二:允许原生事件执行(不推荐)

修改按钮的@onclick事件,允许默认行为和事件冒泡,让Bootstrap原生逻辑生效。但这种方式可能导致模态框显示时数据未更新:

<button type="button" class="btn btn-light mr-1" data-bs-toggle="modal" data-bs-target="#exampleModal" @onclick="(()=> editClick(serv))" @onclick:preventDefault="false" @onclick:stopPropagation="false">
    <!-- svg内容 -->
</button>

额外检查

确保项目中已正确引入Bootstrap的CSS和JS文件,比如在_Layout.cshtml(Server Side)或index.html(WASM)中添加:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:45:28