ASP.NET Core Blazor | Dropdownlist Data from Database


dropdownlist databinding in blazor

This is Part 19 of Web development with Blazor video series. In this video we will discuss how to bind data from a database table to a dropdownlist in ASP.NET Core Blazor. Another common usecase is to bind an Enum to dropdownlist, so we will discuss binding an enum as well.

asp.net blazor dropdownlist from database

In our next video we will discuss how to perform Insert, Update and Delete operations in datagrid. A DropDownList is usually the preferred choice for Gender and Department when we add a new employee or edit an existing employee. Gender is an enum and the list of departments come from a database table.

Enable DataGrid CRUD operations

We will be using Syncfusion DataGrid to perform the CRUD operations. We discussed the basics of DataGrid and setting it up from scratch in Part 4 of this video series.

  1. For the DataGrid to be able to perform CRUD operations it needs to know the primary key column.
  2. To specify the primary key, set IsPrimaryKey property to true.
  3. In this example, EmployeeId column is marked as the primary key.
  4. On <GridEditSettings> component, set AllowAdding="true", AllowEditing="true" and AllowDeleting="true".
@page "/gridedit"
@using Syncfusion.Blazor.Grids

<div style="width:750px">
    <SfGrid DataSource="@Employees" AllowPaging="true"
            Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Delete", "Cancel" })">
        <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true">
        </GridEditSettings>
        <GridPageSettings PageSize="5"></GridPageSettings>
        <GridColumns>
            <GridColumn IsPrimaryKey="true" Field=@nameof(Employee.EmployeeId) HeaderText="ID" 
                        Width="40px"></GridColumn>
            <GridColumn Field=@nameof(Employee.FirstName) HeaderText="First Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.LastName) HeaderText=" Last Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.DateOfBrith) Format="d" 
                        HeaderText="Date of Birth"></GridColumn>
            <GridColumn Field="Department.DepartmentName" HeaderText="Department" Width="140px">
            </GridColumn>
            <GridColumn Field=@nameof(Employee.Gender) HeaderText="Gender" 
                        Width="140px"></GridColumn>
            <GridColumn Field=@nameof(Employee.Email) HeaderText="Email"></GridColumn>
        </GridColumns>
    </SfGrid>
</div>

@code{

    public List<Employee> Employees { get; set; }

    [Inject]
    public IEmployeeService EmployeeService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Employees = (await EmployeeService.GetAllEmployees()).ToList();
    }
}

Binding complex nested properties to datagrid columns

  1. To display employee department name in the datagrid we might do something like the following. 
  2. Department is a complex object.
  3. The following code complies but at runtime we get a null reference exception.
<GridColumn Field=@nameof(Employee.Department.DepartmentName) HeaderText="Department">
</GridColumn>

To bind a complex property such as a Department to a DataGrid column use the following syntax.

<GridColumn Field="Department.DepartmentName" HeaderText="Department">
</GridColumn>

Please note : If you do not see the department name displayed in the Datagrid, in the EmployeeRepository check if the Department is being loaded along with the Employee object.

public class EmployeeRepository : IEmployeeRepository
{
    private readonly AppDbContext appDbContext;

    public EmployeeRepository(AppDbContext appDbContext)
    {
        this.appDbContext = appDbContext;
    }

    public async Task<IEnumerable<Employee>> GetAllEmployees()
    {
        return await appDbContext.Employees.Include(e => e.Department).ToListAsync();
    }
}

Blazor DataGrid Toolbar

Set Toolbar property on the datagrid to display the toolbar icons (Add, Edit, Update, Delete and Cancel)

<SfGrid DataSource="@Employees" AllowPaging="true"
        Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Delete", "Cancel" })">
  • You can edit a row either by double-clicking on the row or by selecting the row and then click on the Edit button in the toolbar.
  • To add a new record click on the Add button in the toolbar.
  • To Save and Cancel use the the respective buttons in the toolbar.

By default a textbox is provided as the interface for Department and Gender columns when adding or editing an employee record.

edit blazor datagrid row

Binding Database data to dropdownlist

Include Syncfusion.Blazor.DropDowns using declaration

@page "/gridedit"
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.DropDowns

<div style="width:750px">
    <SfGrid DataSource="@Employees" AllowPaging="true"
            Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Delete", "Cancel" })">
        <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true">
        </GridEditSettings>
        <GridPageSettings PageSize="5"></GridPageSettings>
        <GridColumns>
            <GridColumn IsPrimaryKey="true" Field=@nameof(Employee.EmployeeId) HeaderText="ID" 
                        Width="40px"></GridColumn>
            <GridColumn Field=@nameof(Employee.FirstName) HeaderText="First Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.LastName) HeaderText=" Last Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.DateOfBrith) Format="d" 
                        HeaderText="Date of Birth"></GridColumn>
            <GridColumn Field="Department.DepartmentName" HeaderText="Department" Width="140px">
                <EditTemplate>
                    <SfDropDownList TItem="Department" TValue="int" DataSource="@Departments"
                                    @bind-Value="@((context as Employee).DepartmentId)" >
                        <DropDownListFieldSettings Text="DepartmentName" Value="DepartmentId">
                        </DropDownListFieldSettings>
                    </SfDropDownList>
                </EditTemplate>
            </GridColumn>
            <GridColumn Field=@nameof(Employee.Gender) HeaderText="Gender" 
                        Width="140px"></GridColumn>
            <GridColumn Field=@nameof(Employee.Email) HeaderText="Email"></GridColumn>
        </GridColumns>
    </SfGrid>
</div>

@code{

    public List<Employee> Employees { get; set; }

    public List<Department> Departments { get; set; }

    [Inject]
    public IEmployeeService EmployeeService { get; set; }

    [Inject]
    public IDepartmentService DepartmentService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Employees = (await EmployeeService.GetAllEmployees()).ToList();
        Departments = (await DepartmentService.GetAllDepartments()).ToList();
    }
}

The following is the HTML specific to the DropDownList

  1. Include <SfDropDownList> inside <EditTemplate>.
  2. Departments property is the DataSource for the dropdownlist.
  3. Departments property is populated with data by the DepartmentService.
<GridColumn Field="Department.DepartmentName" HeaderText="Department" Width="140px">
    <EditTemplate>
        <SfDropDownList TItem="Department" TValue="int" DataSource="@Departments"
                        @bind-Value="@((context as Employee).DepartmentId)" >
            <DropDownListFieldSettings Text="DepartmentName" Value="DepartmentId">
            </DropDownListFieldSettings>
        </SfDropDownList>
    </EditTemplate>
</GridColumn>

IDepartmentService

public interface IDepartmentService
{
    Task<IEnumerable<Department>> GetAllDepartments();
    Task<Department> GetDepartment(int departmentId);
}

DepartmentService

public class DepartmentService : IDepartmentService
{
    private readonly HttpClient httpClient;

    public DepartmentService(HttpClient httpClient)
    {
        this.httpClient = httpClient;
    }

    public async Task<IEnumerable<Department>> GetAllDepartments()
    {
        return await httpClient
            .GetFromJsonAsync<IEnumerable<Department>>("/api/departments");
    }

    public async Task<Department> GetDepartment(int departmentId)
    {
        return await httpClient                
            .GetFromJsonAsync<Department>($"/api/departments/{departmentId}");
    }
}

Register DepartmentService

In the Main() method in Program.cs file register DepartmentService with the dependency injection container.

public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("#app");
        builder.Services.AddHttpClient<IDepartmentService, DepartmentService>(client =>
        {
            client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
        });
        await builder.Build().RunAsync();
    }
}

Binding enum to dropdownlist

<GridColumn Field=@nameof(Employee.Gender) HeaderText="Gender" Width="140px">
    <EditTemplate>
        <SfDropDownList ID="Gender" TItem="string" TValue="Gender" 
                        @bind-Value="@((context as Employee).Gender)" 
                        DataSource="@GenderEnumValues">
        </SfDropDownList>
    </EditTemplate>
</GridColumn>

@code{

    public string[] GenderEnumValues = Enum.GetNames(typeof(Gender));
}




© 2020 Pragimtech. All Rights Reserved.