Search code examples
c#blazor-webassembly

There is no registered property exception, except there should be


I'm trying to teach myself blazor webassembly and I've hit a snag. It's a very simple project, a Blazor Webassembly app with a few modifications.

I'm getting the error:

Unhandled exception rendering component: Cannot provide a value for property '_db' on type
'ChoresAppTheThird.Client.Pages.Users'. There is no registered service of type 
'DataAccessLibrary.IUserData'.

System.InvalidOperationException: Cannot provide a value for property '_db' on type 
'ChoresAppTheThird.Client.Pages.Users'. There is no registered service of type 
'DataAccessLibrary.IUserData'.

There is a registered service, or there should be (from startup.cs):

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddRazorPages();
            services.AddTransient<ISqlDataAccess, SqlDataAccess>();
            services.AddTransient<IUserData, UserData>();
        }

And here is the page that triggers the error:

@page "/users"

@using DataAccessLibrary
@using DataAccessLibrary.Models

@inject IUserData _db

<h3>Users</h3>

@if (people == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table table-striped">
        <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Phone Number</th>
        </tr>
        </thead>
        @foreach (PersonModel user in people)
        {
            <tr>
                <td> @user.Name </td>
                <td> @user.Email </td>
                <td> @user.PhoneNumber </td>
            </tr>
        }
    </table>
}
@code {
    private List<PersonModel> people;

    protected override async Task OnInitializedAsync()
    {
        people = await _db.GetPeople();
    }

}

And here's IUserData/UserData:

    public interface IUserData
    {
        Task<List<PersonModel>> GetPeople();
        Task InsertPerson(PersonModel person);
    }

    public class UserData : IUserData
    {
        private readonly ISqlDataAccess _db;

        public UserData(ISqlDataAccess db)
        {
            _db = db;
        }

        public Task<List<PersonModel>> GetPeople()
        {
            string sql = "select * from Users";
            return _db.LoadData<PersonModel, dynamic>(sql, new { });
        }

        public Task InsertPerson(PersonModel person)
        {
            string sql = @"insert into Users (Name, Email, PhoneNumber)
                        values (@Name, @Email, @PhoneNumber);";

            return _db.SaveData(sql, person);
        }
    }

Any ideas on what I'm doing wrong? I have tried messing with the services somewhat- I've used singleton, scoped, and transient to no difference.


Solution

  • I think your code is not in the right direction for a WASM project.

    In WASM (remember that a WASM project is Single Page Application), you need to create a Rest API call from the client side to get the data from the backend (Database).

    If you use the standard Blazor wizard from Visual Studio and tick the ASP.NET Core Hosted the template will create for you a complete solution, with Client, Server and Shared project.

    enter image description here

    Now you can use this scaffolder to implement you database logic on the Server project. The Client project will call via Rest API your Web API Controller.

    Look at FetchData.razor for the Client side:

    protected override async Task OnInitializedAsync()
        {
            forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
        }
    

    and WeatherForecastController.cs on the Server side:

    [HttpGet]
            public IEnumerable<WeatherForecast> Get()
            {
                var rng = new Random();
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                })
                .ToArray();
            }
    

    In the Server project you can add your database logic.

    Start reading this tutorial from Syncfusion: https://www.syncfusion.com/blogs/post/how-to-build-a-blazor-wasm-crud-application-with-entity-framework.aspx