Blazor 服务器 - “代码隐藏”模式:OnInitializedAsync():找不到合适的方法来覆盖

问题描述 投票:0回答:10

我有一个运行完美的 Blazor(服务器)应用程序,并且遵守

Microsoft.CodeAnalysis.FxCopAnalyzers
StyleCop.Analyzers
设置的所有规则。

大幅删减的剃须刀页面如下:

@inherits OwningComponentBase<MyService>
@inject IModalService ModalService
@inject IJSRuntime JSRuntime

// UI code

@code
{
    private readonly CancellationTokenSource TokenSource = new CancellationTokenSource();
    ElementReference myElementReferenceName;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await this.myElementReferenceName.FocusAsync(this.JSRuntime);
    }

    protected override async Task OnInitializedAsync()
    {
        ....
    }

    public void Dispose()
    {
        this.TokenSource.Cancel();
    }

    protected void ShowModalEdit(object someObject)
    {
        .....
        Modal.Show<MyPage>("Edit", parameters);
    }
}

注#1:我根据

Daniel Roth 的建议
使用了 @inherits OwningComponentBase<MyService>

注#2:我正在使用 Chris Sainty 的 Modal 组件 组件

但是,当我尝试将所有代码从

@code {...}
部分移动到“代码隐藏”部分类(“MyPage.razor.cs”)时,我遇到了以下错误....

“MyPage”不包含“Service”的定义且无法访问 扩展方法“服务”接受.....

'MyPage.OnAfterRenderAsync(bool)':找不到合适的方法来覆盖

'MyPage.OnInitializedAsync()':找不到合适的方法来覆盖

类型“MyPage”不能用作泛型中的类型参数“T” 类型或方法 'IModalService.Show(string, ModalParameters, 模态选项)'。没有隐式引用转换 “MyPage”到“Microsoft.AspNetCore.Components.ComponentBase”。

建议?

code-behind blazor blazor-server-side
10个回答
13
投票

您的

MyPage.razor.cs
应继承自
ComponentBase
类,并且您的
Mypage.razor
应继承自
MyPage.razor.cs

在“代码隐藏”类中,您应该为要注入的每个服务使用

[Inject]
属性,并使它们至少具有
protected
属性,以便能够在剃刀组件中使用它们。

下面是我的一个测试应用程序的示例,请注意,它使用 .net-core 3.0,在 3.1 中您可以使用部分类。

索引.razor

@page "/"
@inherits IndexViewModel

<div class="row">
    <div class="col-md">

        @if (users == null)
        {
            <p><em>Hang on while we are getting data...</em></p>
        }
        else
        {
            <table class="table">
                <thead>
                    <tr>
                        <th class="text-danger">Id</th>
                        <th class="text-danger">Username</th>
                        <th class="text-danger">Email</th>
                        <th class="text-danger">FirstName</th>
                        <th class="text-danger">LastName</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var user in users)
                    {
                        <tr>
                            <td>@user.Id</td>
                            <td>@user.Username</td>
                            <td>@user.Email</td>
                            <td>@user.FirstName</td>
                            <td>@user.LastName</td>
                        </tr>
                    }
                </tbody>
            </table>
        }
    </div>
</div>

IndexViewModel.cs

public class IndexViewModel : ComponentBase, IDisposable
{
    #region Private Members
    private readonly CancellationTokenSource cts = new CancellationTokenSource();
    private bool disposedValue = false; // To detect redundant calls

    [Inject]
    private IToastService ToastService { get; set; }
    #endregion

    #region Protected Members
    protected List<User> users;

    [Inject] IUsersService UsersService { get; set; }

    protected string ErrorMessage { get; set; }

    #endregion

    #region Constructor

    public IndexViewModel()
    {
        users = new List<User>();
    }

    #endregion

    #region Public Methods


    #endregion

    #region Private Methods

    protected override async Task OnInitializedAsync()
    {
        await GetUsers().ConfigureAwait(false);
    }

    private async Task GetUsers()
    {
        try
        {
            await foreach (var user in UsersService.GetAllUsers(cts.Token))
            {
                users.Add(user);
                StateHasChanged();
            }
        }
        catch (OperationCanceledException)
        {
            ShowErrorMessage($"{ nameof(GetUsers) } was canceled at user's request.", "Canceled");
        }

        catch (Exception ex)
        {
            // TODO: Log the exception and filter the exception messages which are displayed to users.
            ShowErrorMessage(ex.Message);
        }
    }

    private void ShowErrorMessage(string message, string heading ="")
    {
        //ErrorMessage = message;
        //StateHasChanged();
        ToastService.ShowError(message, heading);
    }

    private void ShowSuccessMessage(string message, string heading = "")
    {
        ToastService.ShowSuccess(message, heading);
    }

    protected void Cancel()
    {
        cts.Cancel();
    }
    #endregion

    #region IDisposable Support

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                cts.Dispose();
            }

            disposedValue = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        // TODO: uncomment the following line if the finalizer is overridden above.
        // GC.SuppressFinalize(this);
    }
    #endregion
}

11
投票

TLDR

确保您的

razor.cs
文件中的命名空间正确

更长的解释

就我而言,当我将类放入错误的命名空间时,我收到了此错误。

page.razor.cs
文件与
page.razor
文件位于同一目录中,并且它包含部分类 ,已被 2019 年 10 月更新接受

但是,即使文件位于

path/to/dir
中,
page.razor.cs
的命名空间为
path.to.another.dir
,这导致抛出此错误。只需将命名空间更改为
path.to.dir
就可以修复此错误!


5
投票

当我使用部分类方法时,我遇到了这个错误,并且我正在尝试构建 Identity。我改成基类方法就解决了。

我在添加组件后使用的部分类,比如说

MyComponent
,我向
MyComponent.razor.cs
添加了一个类用于注入服务:

public BuildingServices Services { get; set; }

对于添加

MyComponent
后的基类方法,我添加了一个类来
MyComponent.razor.cs
更改类名并使其继承自
componentBase

MyComponentBase : ComponentBase

我把它放在

MyComponent.razor
的顶部:

@inherits MyComponentBase

使用 protected 关键字使您的方法易于访问。


0
投票

以上几点都是非常正确的。 FWIW,只是为了添加我在这个问题上发现的一个奇怪的事情;我无法让这个错误消失。一切都被宣布为应有的样子。一旦排除了所有潜在的编码问题,我发现退出 VS,返回并重建可以解决问题。几乎就像 VS 不会放过那个错误一样。


0
投票

花了两天时间清理、重建……结果发现是剪切和粘贴错误。我从另一个类似的类复制了 razor 文件,并错误地将其留在顶部:

@inject Microsoft.Extensions.Localization.IStringLocalizer<Person> localizer

“Person”是错误的类,它不是由任何 include 语句定义的。由于某些奇怪的原因,唯一的错误是“OnInitialized() 找不到可以覆盖的方法。”


0
投票

我在升级到6.0时发现了这一点。我必须从使用基类切换到使用部分类!


0
投票

对我来说,诀窍是将 .razor 文件拖到共享文件夹中,然后将其拖回原始文件夹。根据 spmoran-blazor 在 GitHub

上的回答

0
投票

这种错误可能有多种原因。就我而言,这很奇怪,我认为我最近更改了什么,它是更新的 .Net 7 SDK 的安装。我卸载了它,留下了与 VS 2022 一起安装的原始 .NET,现在一切都可以编译,而不是出现此类 69 错误。


0
投票

MyComponent.razor 文件:

<h1>@Message</h1>

MyComponent.razor.cs 文件:

using Microsoft.AspNetCore.Components;

namespace MyProject.Client.Shared;

public class MyComponent : ComponentBase
{
    string Message = "Hello";
}

有时visual studiosteel 在错误列表窗口中显示错误。确保您build blazor 项目是否有错误。


0
投票

我有 Blazor .net 7 VS 2022。我遇到了同样的问题,我创建了新文件夹并一一复制所有文件并解决了问题。谢谢你,尤金。

© www.soinside.com 2019 - 2024. All rights reserved.