Blazor Server - 'Code Behind' pattern: OnInitializedAsync(): no suitable method found to override
Your MyPage.razor.cs
should inherit from ComponentBase
class and your Mypage.razor
should inherit from MyPage.razor.cs
.
In your "code-behind" class you should use [Inject]
attribute for every service you are injecting and make them at least protected
properties to be able to use them in your razor components.
Below is an example from one of my testing apps, please note this uses .net-core 3.0, in 3.1 you can use partial classes.
Index.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
}
Hope this helps.
Came across this error when I used partial class approach and I was trying to scaffold Identity. I changed to base class aprroach it was resolved.
partial class I was using after adding a component say MyComponent, add a class MyComponent.razor.cs for injecting services use
[Inject] public BuildingServices Services { get; set; }
for base class approach
after adding a after adding a component say MyComponent, add a class MyComponent.razor.cs change the class name and make it inherit from componentBase MyComponentBase : ComponentBase
and place this at the top of MyComponent.razor
@inherits MyComponentBase
Use protected keyword to make your methods accessible