ASP .NET Core - Dropdownlist com Banco de dados


Hoje vamos recordar como vincular um dropdownlist a um banco de dados na ASP .NET Core 5.0.

Neste artigo vamos usar o mecanismo de visualização do razor e iremos vincular uma lista suspensa a um banco de dados SQL Server usando ADO.NET.

Talvez a abordagem mais usada seja usar o EF Core mas para variar vamos usar ADO .NET que é uma forma muito simples de vincular a lista suspensa.

Neste exemplo, vamos usar o banco de dados Northwind e exibir os dados dos funcionários e dos clientes a partir das tabelas Employees e Customers e exibir em um dropdownlist.

Nota: Baixe o Northwind aqui.

Podemos usar tanto o Visual Studio Code como o VS 2019 Community e neste exemplo vou usar este último na versão 16.8.0 no ambiente .NET Core SDK 5.0.

Vamos criar um projeto e ASP .NET Core MVC usando a versão 5.0:    

Precisamos incluir no projeto o pacote System.Data.SqlClient pois vamos usar os recursos da ADO .NET e também precisamos incluir no arquivo appsettings.json a string de conexão do banco de dados Northwind:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=express;Initial Catalog=Northwind;Integrated Security=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Definindo o modelo de domínio

Na pasta Models vamos criar as entidades que vão representar o nosso modelo de domínio. Vamos usar classes POCO totalmente anêmicas e sem lógica alguma pois iremos usá-los apenas como DTO.

Vamos criar as seguintes classes:

1- EmployeeList

public class EmployeeList
{
   public int EmployeeID { get; set; }
   public string FirstName { get; set; }
}

2- CustomerList

public class CustomerList
{
   public string CustomerID { get; set; }
   public string ContactName { get; set; }
}

3- DropdownList

using System.Collections.Generic;

namespace AspnDropdownDB.Models
{
     public class DropdownList
     {
          public List<EmployeeList> Employees { get; set; }
          public List<CustomerList> Customers { get; set; }
     }
}

Creio que analisando o código das classes fica clara a nossa intenção de mapear as entidades com as propriedades para as respectivas tabelas e ter um DTO contendo a lista de funcionários e clientes que vamos exibir.

Criando e registrando serviço

Vamos criar um serviço para obter os dados do banco de dados Northwind e assim desacoplar a lógica de acessar os dados do nosso controlador HomeController.

Vamos criar uma pasta Services e a seguir criar a classe NorthwinService:

using AspnDropdownDB.Models;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
namespace AspnDropdownDB.Services
{
    public class NorthwindService
    {
        public IConfigurationRoot GetConnection()
        {
            var builder = new ConfigurationBuilder()
                                  .SetBasePath(Directory.GetCurrentDirectory())
                                  .AddJsonFile("appSettings.json").Build();
   
            return builder;
        }

        public List<CustomerList> GetCustomerList()
        {
            var connection = GetConnection().GetSection("ConnectionStrings")
                                       .GetSection("DefaultConnection").Value;
            SqlConnection con = new SqlConnection(connection);
            SqlCommand cmd = new SqlCommand("Select CustomerID, ContactName From Customers", con);
            con.Open();

            SqlDataReader idr = cmd.ExecuteReader();
            List<CustomerList> customers = new List<CustomerList>();

            if (idr.HasRows)
            {
                while (idr.Read())
                {
                    customers.Add(new CustomerList
                    {
                        CustomerID = Convert.ToString(idr["CustomerID"]),
                        ContactName = Convert.ToString(idr["ContactName"]),
                    });
                }
            }
            con.Close();
            return customers;
        }
        public List<EmployeeList> GetEmployeeList()
        {
            var connection = GetConnection().GetSection("ConnectionStrings")
                                      .GetSection("DefaultConnection").Value;
            SqlConnection con = new SqlConnection(connection);
            SqlCommand cmd = new SqlCommand("Select EmployeeID,FirstName From Employees", con);
            con.Open();
            SqlDataReader idr = cmd.ExecuteReader();
            List<EmployeeList> Employees = new List<EmployeeList>();
            if (idr.HasRows)
            {
                while (idr.Read())
                {
                    Employees.Add(new EmployeeList
                    {
                        EmployeeID = Convert.ToInt32(idr["EmployeeID"]),
                        FirstName = Convert.ToString(idr["FirstName"]),
                    });
                }
            }
            con.Close();
            return Employees;
        }
    }
}

Este monte de código faz o seguinte:

  1. Obtém a string de conexão no arquivo appsettings.json
  2. Acessa a tabela Customers e gera uma lista de customers com ID e nome;
  3. Acessa a tabela Employees e gera uma lista de employees com ID e nome;

Vamos registrar o serviço no container DI nativo da ASP .NET Core no método ConfigureServices da classe Startup:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddScoped<NorthwindService>();
}

Definindo o controlador e a view

Vamos usar o controlador HomeController já criado na pasta Controllers e alterar o seu código conforme abaixo:

using AspnDropdownDB.Models;
using AspnDropdownDB.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
namespace AspnDropdownDB.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly NorthwindService _service;
        public HomeController(ILogger<HomeController> logger, NorthwindService service)
        {
            _logger = logger;
            _service = service;
        }
        public IActionResult Index()
        {
            DropdownList dropdownlist = new DropdownList
            {
                Customers = _service.GetCustomerList(),
                Employees = _service.GetEmployeeList()
            };
            return View(dropdownlist);
        }
        public IActionResult Privacy()
        {
            return View();
        }
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

Injetamos o serviço no construtor e a partir da sua instância obtemos a lista de clientes e funcionários.

A seguir basta alterar o código da view Index.cshtml na pasta Views/Home:

@model AspnDropdownDB.Models.DropdownList
@{
    ViewData["Title"] = "Home Page";
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>
        Vinculando DropdownList com SQL Server
    </title>
</head>
<body>
             Cliente
            <div class="col-md-3">
                @Html.DropDownListFor(model => model.Customers, new SelectList(Model.Customers, "CustomerID", "ContactName")
, new { @class = "form-control" })
            </div>
            <br />
            Funcionário
            <div class="col-md-3">
                @Html.DropDownListFor(model => model.Employees, new SelectList(Model.Employees, "EmployeeID", "FirstName")
, new { @class = "form-control" })
            </div>
</body>
</html>

Aqui usamos o html helper @Html.DropDownListFor() passando a lista de clientes e funcionários e exibindo o nome.

Executando o projeto teremos:

Pegue o código do projeto aqui:   AspnDropdownDB.zip (sem as referências)

"Porque do céu se manifesta a ira de Deus sobre toda a impiedade e injustiça dos homens, que detêm a verdade em injustiça."
Romanos 1:18

Referências:


José Carlos Macoratti