Search code examples
c#razorblazorblazor-webassemblyasp.net-blazor

Blazor Code-Behind: Why Is OnInitialized Not Finding Its Overridden Method?


I am using .NET 6.0.100-preview.6.21355.2 in Visual Studio 2022. I started with the WebAssembly templates, then followed this YouTube tutorial for implementing SQL via HTTP API under WebAssembly. The tutorial has a GitHub page with its code.

All of that was working fine, and then I decided to move the code out of the Razor pages and into code-behind pages. The first page (counter.razor / counter.razor.cs) worked fine, but the second page is giving me problems. Specifically, I am getting a no suitable method found to override error in Intellisense for OnInitialized.

OnInitialized has an empty signature, just as it did when it was on CreateForecast.razor and as it does in this Microsoft document. So why the error? Oddly, I receive the same error if I return the code into the base Razor page. There are a few other Intellisense errors, but I suspect including those would be asking more than one question at a time :-).

I've also tried looking up the OnInitialized signature to ensure there isn't something weird going on there. It is listed in ComponentBase as protected void virtual, with no parameters. So, I would expect that a protected override void method with no parameters in a descendant class would match that.

Here is CreateForecast.Razor:

@page "/createforecast"
@using CART.Shared
@using CART.Client
@inherits CreateForecast

<h3>Create Forecast</h3>

<div class="row">
    <EditForm Model="@Forecast" OnValidSubmit="InsertForecast">
        <div class="form-group">
            <label>Date: </label>
            <InputDate @bind-Value="Forecast.Date" />
        </div>

        <div class="form-group">
            <label>Temperature (C): </label>
            <InputNumber @bind-Value="Forecast.TemperatureC" />
        </div>

        <div class="form-group">
            <label>Summary: </label>
            <InputText @bind-Value="Forecast.Summary" />
        </div>

        <div class="form-group">
            <input type="submit" class="btn btn-success" value="Create forecast" />
            <NavLink href="fetchData" class="btn btn-info">Back to forecasts</NavLink>
        </div>

    </EditForm>

</div>

(CART is the name of the application.)

Here is CreateForecast.Razor.cs:

using CART.Shared;
using Microsoft.AspNetCore.Components;
using System;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Json;

namespace CART.Client.Pages
{
    public partial class CreateForecast : ComponentBase
    {
        public WeatherForecast Forecast { get; set; }
        public HttpClient httpClient;
        public NavigationManager navigationManager;
        
        protected override void OnInitialized()
        {
            Forecast.Date = DateTime.Today;
        }        

        public async Task InsertForecast()
        {
            await httpClient.PostAsJsonAsync("/api/weatherforecast", Forecast);
            navigationManager.NavigateTo("/fetchdata");
        }
    }
}

Solution

  • You should remove the line

    @inherits CreateForecast
    

    I checked, adding @inherits does produce:

    Error CS0115 'FetchData.BuildRenderTree(RenderTreeBuilder)': no suitable method found to override...

    That was not obvious.

    @inherits was used in older versions of Blazor when the classes were not yet generated as partial.

    Now they are partial and you are trying to inherit a class from itself.

    Side note, in CreateForecast.Razor.cs you can shorten the defintion to

    //public partial class CreateForecast : ComponentBase
      partial class CreateForecast 
    

    this reduces clutter and the chance for errors.