Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect Blazor WebAssembly to DataBase

I recently started developing a Blazor WebAssembly app, and now I'm settling on a database connection.

All lessons and instructions say that you need to enter information into the Startup.cs file and appsettings.json, but these files are not in the project.

I do not understand. In Blazor WebAssembly, is there no way to connect to the DB?

like image 466
Евгений Ляшенко Avatar asked Sep 21 '20 16:09

Евгений Ляшенко


People also ask

Where do I deploy Blazor WebAssembly?

Blazor WebAssembly apps can be deployed to Azure App Services on Windows, which hosts the app on IIS. Deploying a standalone Blazor WebAssembly app to Azure App Service for Linux isn't currently supported.

How do I use localStorage in Blazor WebAssembly?

To access browser localStorage in Blazor apps, write a custom code or use a third party package. The difference between localStorage and sessionStorage is: The localStorage is scoped to the user's browser. If the user reloads the page or closes and reopens the browser, the state persists.

Should I use Blazor server or Blazor Wasm?

The Blazor Server hosting model offers several benefits: Download size is significantly smaller than a Blazor WebAssembly app, and the app loads much faster. -The app takes full advantage of server capabilities, including the use of . NET Core APIs.


3 Answers

Not directly. Blazor WebAssembly is a front end framework. You need to create an API controller to wrap your database connection and use HttpClient to call the api. A straight forward way to do it is to use an asp.net core web api controller wrapping an Entity Framework Core Database context.

@inject HttpClient Http
<template_html_here/>
    @code 
    {
         protected override async Task OnInitializedAsync()
        {
            products = await Http.GetFromJsonAsync<Product[]>("api/Products");
        }
    }

Controller:

 [ApiController]
 [Route("api/[controller]")]
 public class ProductsController : ControllerBase
    {
       
        private readonly ProductsDbContext _context; // your database context

        public ProductsController(ProductsDbContext context)
        {
            _context = context;
        }

        [HttpGet]
        public IEnumerable<Product> Get()
        {
           return _context.Products.ToList();
        }
    }

You can read more about blazor at https://learn.microsoft.com/en-us/aspnet/core/blazor/call-web-api?view=aspnetcore-3.1. And on asp.net core web APIs on https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio.

like image 188
codinbear107 Avatar answered Oct 27 '22 16:10

codinbear107


If you are referring to local storage (browser storage) then this component by Chris Sainty could help you.

However if you are looking for a connection to a Database like a SQL Server or document storage like Mongo it can not be done directly.

Blazor Wasm is for front end development. You will need to call web APIs that connect to databases stored on servers.

like image 31
CobyC Avatar answered Oct 27 '22 18:10

CobyC


It is now 2022. .NET 6 has shipped, and Blazor WebAssembly has support for compiled binaries.

That means there are now three options for using a database in a Blazor WebAssembly application.

#1. Create a webApi. Call the webApi on from the client as you can see being done in the default sample. See FetchData.razor

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

and WeatherForecastController.cs on the server. The default solution does not call a database, but you could easily use a dbContext in Get() to pull data from a database.

#2: With support for compiled binaries in Blazor WebAssembly, it is now possible to completely host Sqlite in WebAssembly.

https://github.com/TrevorDArcyEvans/BlazorSQLiteWasm

#3: IndexedDb. Through js interop, the IndexDb in the browser can be used. Large amounts of data can be stored in this Db, and like the name implies, it is indexed. Since this can be accidentally cleared, it is most useful in a PWA, where that is more difficult. Also, with this and Sqlite, anything done in the browser is open to the user and hackers that compromise the user's maching.

I use https://github.com/wtulloch/Blazor.IndexedDB

You add schema in program.cs:

builder.Services.AddIndexedDB(dbStore =>
{
    dbStore.DbName = "SomeDbName";
    dbStore.Version = 1;
    dbStore.Stores.Add(new StoreSchema
    {
        Name = "People",
        PrimaryKey = new IndexSpec { Name = "id", KeyPath = "id", Auto = false },
        Indexes = new List<IndexSpec>
        {
            new IndexSpec{Name="alias",  KeyPath = "alias", Auto=false},
            new IndexSpec{Name="isAvailable", KeyPath = "isAvailable", Auto=false},
            new IndexSpec{Name="communityId", KeyPath = "communityId", Auto=false},
            new IndexSpec{Name="isFriend", KeyPath = "isFriend", Auto=false},
        }
    });
});

In this code, the names of the fields are camelCased, whereas the objects I'm constructing are PascalCase. This was actually necessary for me to get it to work. I think my serializer may be set to camelCase Json or something, so watch that.

And then you add remove and search using:

public async Task AddPersonAsync(LocalPerson member)
{
    var newPerson = new StoreRecord<LocalPerson>
    {
        Data = member,
        Storename = PeopleStoreName
    };
    await _dbManager.AddRecord(newPerson);
}
public async Task<LocalPerson> GetPersonByIdAsync(Guid id)
{
    var localPerson = await _dbManager.GetRecordById<Guid, LocalPerson>(PeopleStoreName, id);
    return localPerson;
}
public async Task<List<LocalPerson>> GetPeopleAsync()
{
    var results = await _dbManager.GetRecords<LocalPerson>(PeopleStoreName);
    return results;
}

public async Task<List<LocalPerson>> GetPeopleByCommunityAsync(Guid id)
{
    var indexSearch = new StoreIndexQuery<Guid>
    {
        Storename = PeopleStoreName,
        IndexName = "communityId",
        QueryValue = id,
    };
    var result = await _dbManager.GetAllRecordsByIndex<Guid, LocalPerson>(indexSearch);

    if (result is null)
    {
        return new List<LocalPerson>();
    }

    return (List<LocalPerson>)result;
}
like image 6
Parrhesia Joe Avatar answered Oct 27 '22 18:10

Parrhesia Joe