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

为何Blazor模态框无法返回选中的Contact对象?编译报错CS1503

解决Blazor模态框的CS1503错误及无法返回选中对象问题

问题根源

  1. CS1503错误原因:modal-test.razor和modal.razor中各自定义了同名的Contact类,但这两个类属于不同的组件作用域,是完全独立的类型。父组件绑定OnSave="HandleSave"时,HandleSave接收的是自身定义的Contact,而子组件Modal的EventCallback<Contact>用的是子组件内部的Contact,类型不匹配导致转换失败。
  2. 无法返回选中对象:本质也是上述类型不匹配问题,子组件触发OnSave传递的是自身的Contact实例,父组件无法识别为自己的Contact类型,导致赋值失败。

修复步骤

1. 提取共享的Contact类

在项目的Shared文件夹下创建Contact.cs文件,将Contact类统一放在这里:

namespace BlazorApp1.Shared;

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
}

2. 修改modal-test.razor组件

删除组件内部的Contact类,引用共享的Contact类型,并将HandleSave改为异步方法(符合Blazor EventCallback的最佳实践):

@page "/modal-test"
@using BlazorApp1.Shared

<button @onclick="OpenModal">Open Modal</button>

<Modal OnSave="HandleSave" @ref="modal"></Modal>

<p>Selected contact: @SelectedContact?.Name</p>

@code {
    private Modal modal;
    private Contact SelectedContact;

    private void OpenModal()
    {
        modal?.Open();
    }

    private async Task HandleSave(Contact contact)
    {
        SelectedContact = contact;
    }
}

3. 修改modal.razor组件

同样删除内部的Contact类,引用共享的Contact类型:

@page "/modal"
@using BlazorApp1.Shared

<div class="modal @ModalClass" tabindex="-1" role="dialog" style="display:@ModalDisplay" aria-labelledby="modalTitle" aria-describedby="modalBody" aria-hidden="@(!ShowBackdrop)">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="modalTitle">Select a Contact</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close" @onclick="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body" id="modalBody">
                <ul>
                    @foreach (var contact in Contacts)
                    {
                        <li @onclick="() => SelectContact(contact)">@contact.Name</li>
                    }
                </ul>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="Close">Close</button>
            </div>
        </div>
    </div>
</div>

@if (ShowBackdrop)
{
    <div class="modal-backdrop fade show"></div>
}

@code {
    public string ModalDisplay { get; set; } = "none;";
    public string ModalClass { get; set; } = "";
    public bool ShowBackdrop { get; set; } = false;

    [Parameter]
    public EventCallback<Contact> OnSave { get; set; }

    private List<Contact> Contacts = new List<Contact>
    {
        new Contact { Id = 1, Name = "John Doe" },
        new Contact { Id = 2, Name = "Jane Smith" },
        new Contact { Id = 3, Name = "Bob Johnson" }
    };

    public void Open()
    {
        ModalDisplay = "block;";
        ModalClass = "show";
        ShowBackdrop = true;
        StateHasChanged();
    }

    public void Close()
    {
        ModalDisplay = "none";
        ModalClass = "";
        ShowBackdrop = false;
        StateHasChanged();
    }

    private async Task SelectContact(Contact contact)
    {
        if (OnSave.HasDelegate)
        {
            await OnSave.InvokeAsync(contact);
        }
        Close();
    }
}

额外说明

  • 确保两个组件都正确引用了项目实际的共享命名空间(示例中为BlazorApp1.Shared)。
  • 将HandleSave改为异步方法是因为EventCallback.InvokeAsync返回Task,异步方法能更好地兼容Blazor组件生命周期,避免潜在的UI更新问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:13:16