관리 메뉴

웹개발자의 기지개

[ASP.NET Core MVC] 두개의 Select문 만들기 (시도, 구군 주소 선택하기) - Dapper 이용 본문

ASP.NET/ASP.NET Core

[ASP.NET Core MVC] 두개의 Select문 만들기 (시도, 구군 주소 선택하기) - Dapper 이용

http://portfolio.wonpaper.net 2022. 12. 12. 23:14

 

실무에서 자주 접하는 시도 , 구군 선택하는 입력폼이다.

 

우선 주소관련 DB 이다.

필자의 깃허브에 올려놓았다. (시도, 구군, 구군동)

https://github.com/wonpaper/sido_gugun_dong

 

GitHub - wonpaper/sido_gugun_dong: 시도_구군, 시도_구군_동 mysql DB

시도_구군, 시도_구군_동 mysql DB. Contribute to wonpaper/sido_gugun_dong development by creating an account on GitHub.

github.com

 

ASP.NET Core MVC의 기본 방식으로 코딩하였다.

다만, MyMVCTest1.Models 처럼 별도의 클래스 라이브러리로 새로 프로젝트 추가해 놓았으며,  이 프로젝트에  각종 클래스와 리포지터리를 만들었다.

 

[ appsettings.json ] - DB 연결자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionString": {
    "AppDb": "Server=DESKTOP-ASIDMUS;Database=MyDB2;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "ConnectionStrings": "Server=DESKTOP-ASIDMUS;Database=IdeaApp;Trusted_Connection=True;MultipleActiveResultSets=true"
}
 
cs

위의 소스에서 ConnectionString 안에 AppDb 연결자 값을 이용하였다. 추가로 원하는 다른 DB의 연결자도 연이어 만들수 있다.

 

[ MyMVCTest1.Models/AddressPkg/AddressSido.cs ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
 
namespace MyMVCTest1.Models.AddressPkg
{
    public class AddressSido
    {
        [Key]
        public int Id { get; set; }
        public string Si { get; set; }
        public string Gu { get; set; }
    }
}
cs

 

[ MyMVCTest1.Models/AddressPkg/IAddressSido.cs ] - interface 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Text;
 
namespace MyMVCTest1.Models.AddressPkg
{
    public interface IAddressSido
    {
        List<AddressSido> GetAll();
 
        List<AddressSido> GetAll(string si);
 
        AddressSido Get(string si, string gu);
 
    }
}
 
cs

[ MyMVCTest1.Models/AddressPkg/AddressSidoRepository.cs ] - Sido Repository 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using Dapper;
using Microsoft.Extensions.Configuration;
using MyMVCTest1.Models;
 
namespace MyMVCTest1.Models.AddressPkg
{
    public class AddressSidoRepository : IAddressSido
    {
 
        private readonly IDbConnection db;
        private readonly IConfiguration config;
        public AddressSidoRepository(IConfiguration config)
        {
            this.config = config;
            db = new SqlConnection(this.config.GetSection("ConnectionString").GetSection("AppDb").Value);
        }
 
 
        public List<AddressSido> GetAll()
        {
            string sql = "select distinct(si) as si from zipcode1 order by si ASC";
            return db.Query<AddressSido>(sql).ToList();
        }
 
        /// <summary>
        /// 시도 키워드 넣고 검색
        /// </summary>
        /// <param name="si">시도</param>
        /// <returns></returns>
        public List<AddressSido> GetAll(string si)
        {
            string sql = "select * from zipcode1 where si= @Si order by si ASC, gu ASC";
            return db.Query<AddressSido>(sql, new { Si = si }).ToList();
        }
 
 
        /// <summary>
        /// 시도, 구군 키워드 넣고 검색
        /// </summary>
        /// <param name="si">시도</param>
        /// <param name="gu">구군</param>
        /// <returns></returns>
        public AddressSido Get(string si, string gu)
        {
            string sql = "select * from zipcode1 where si= @Si and gu= @Gu";
            return db.Query<AddressSido>(sql, new { Si = si, Gu = gu }).FirstOrDefault();
        }
    }
}
 
cs

AddressSidoRepository는 IAddressSido 인터페이스를 상속하여 sido 관련 여러가지 매니저관리 기능을 한다.

별도의 EF 를 이용하지 않고 여기서는 Dapper 라이브러리를 이용하였다.

 

그리고, Startup.cs 에서 IAddressSido 와 AddressSidoRepository 에 대해 종속성 주입을 했다.

 ASP.Net Core 3.1 을 기준으로 코딩해서 Startup.cs 에서 처리했으나, 6.0 에서는 Program.cs 내에서 동일하게 처리하면 된다.

 

[ Startup.cs ] 소스 중에서

1
2
3
4
5
6
7
8
public void ConfigureServices(IServiceCollection services)
{
......
    // AddressSido 종속성 주입
    services.AddTransient<IAddressSido, AddressSidoRepository>();
......
 
}
cs

 

 

 

이제는 실제 MVC 를 만들어 본다.

[ AddressPkgController.cs ] - 콘트롤러

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using Microsoft.AspNetCore.Mvc;
using MyMVCTest1.Models;
using MyMVCTest1.Models.AddressPkg;
using System.Collections.Generic;
 
namespace MyMVCTest1.Controllers
{
    public class AddressPkgController : Controller
    {
        private IAddressSido addressSidoRepository;
        public AddressPkgController(IAddressSido addressSidoRepository)
        {
            this.addressSidoRepository = addressSidoRepository;
        }
 
        public IActionResult Index()
        {
            return View();
        }
 
 
        [HttpGet]
        public IActionResult ListType1(string sido)
        {   if (sido == null)
            {
                var sidoList = addressSidoRepository.GetAll();
                ViewBag.SidoList = sidoList;
            } else
            {
                var sidoList = addressSidoRepository.GetAll();
                var gugunList = addressSidoRepository.GetAll(sido);
 
                ViewBag.SidoList = sidoList;
                ViewBag.GugunList = gugunList;
            }
 
            return View();
        }
 
 
    }
}
 
cs

11라인은 생성자 종속성 주입 DI 형태로 addressSidoRepository 객체를 얻어온다.  

23라인에서 Get 방식의 실제 시도, 구군 내용을 DB 에서 불러와서 ViewBag에 List 시도 결과물을 만들어 놓는다.

 

[ ListType1.cshtml ] - View 페이지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@using MyMVCTest1.Models.AddressPkg
@using Microsoft.AspNetCore.Http
 
<form name="f" method="post">
 
<h2>주소 (시도 / 구군)</h2>
<br />
 
<label for="sido">시도</label>
<select id="sido" name="sido" class="form-control" onchange="sidoChg()">
    <option value="">= 시도 =</option>
    @foreach (var sido in ViewBag.SidoList) {
        @if (Context.Request.Query["sido"].ToString() == sido.Si) {
           <option value="@sido.Si" selected>@sido.Si</option>
        } else {
           <option value="@sido.Si">@sido.Si</option>
        }
    }
</select>
 
<br /><br />
 
<label for="gugun">구군</label>
<select id="gugun" name="gugun" class="form-control">
    @if (ViewBag.GugunList == null) {
        <option value="">= 구군 =</option>
    } else {
        @foreach (var gugun in ViewBag.GugunList)
        {
            <option value="@gugun.Gu">@gugun.Gu</option>
        }
    }
</select>
 
</form>
 
<script>
function sidoChg() {
    var form = document.f;
    var sido = form.sido.value;
    location.href="?sido=" + sido;
}
</script>
cs

콘트롤러에서 ViewBag 형태로 보내준 List 형의 관련 결과물을 View 페이지에서 Select 문에서 foreach 문을 돌려서

option 을 만들어 넣는다.

 

 

 

 

 

 

 

 

 

 

Comments