예약 종류 관리 ASP.NET Core Razor Pages 애플리케이션
안녕하세요. 이번에는 AppointmentsTypes 테이블을 이용하여 예약 종류를 관리하는 방법을 설명하겠습니다. 이 강좌에서는 다음과 같은 단계로 진행됩니다.
- ASP.NET Core 프로젝트 생성
- 데이터베이스 테이블 생성
- 모델 클래스 생성
- 리포지토리 클래스 생성
- Razor Pages에 직접 Repository 클래스 사용
각 단계를 차례대로 진행하면서, 예약 종류를 관리하는 ASP.NET Core Razor Pages 앱을 만들어 보겠습니다.
완성된 기본 형태는 다음 그림과 같습니다.
0. VisualAcademy 프로젝트
먼저, Visual Studio에서 VisualAcademy라는 이름의 새로운 ASP.NET Core Razor Pages 프로젝트를 생성합니다. 생성 후에 다음 단계를 따라주세요.
- 프로젝트에 Models 폴더를 만듭니다.
- Models 폴더에 AppointmentsTypeRepository.cs, IAppointmentsTypeRepository.cs 및 AppointmentType.cs 파일을 추가합니다.
이제 프로젝트 구조가 다음과 같이 설정되어 있어야 합니다.
VisualAcademy
│
├── Models
│ ├── AppointmentsType.cs
│ ├── AppointmentsTypeRepository.cs
│ └── IAppointmentsTypeRepository.cs
│
├── Pages
│ └── ...
│
├── Program.cs
├── (Startup.cs)
└── ...
AppointmentsTypeRepository
클래스를 사용하기 전에, 프로젝트에 Dapper 라이브러리를 설치해야 합니다. 이를 위해 NuGet 패키지 관리자를 사용하거나 프로젝트 폴더에서 다음 명령을 실행하세요.
dotnet add package Dapper
다음으로, Program.cs(Startup.cs)
파일을 열어 ConfigureServices
메서드 영역에서 AppointmentsTypeRepository
를 DI 컨테이너에 등록하세요. 이렇게 하려면, ConnectionStrings
섹션에 데이터베이스 연결 문자열을 추가하고, AppSettings.json
파일에서 데이터베이스 연결 문자열을 가져옵니다.
// Program.cs(Startup.cs)
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
string connectionString = Configuration.GetConnectionString("DefaultConnection");
services.AddSingleton<IAppointmentsTypeRepository>(
new AppointmentsTypeRepository(connectionString));
}
따로 TenantConnection을 사용하는 경우라면 다음과 같이 설정합니다.
string connectionString = Configuration.GetConnectionString("TenantConnection");
services.AddSingleton<IAppointmentsTypeRepository>(new AppointmentsTypeRepository(connectionString));
이제 프로젝트가 설정되었으며, Razor Pages에서 AppointmentsTypeRepository 클래스를 사용하여 예약 종류의 CRUD 작업을 구현할 수 있습니다. Razor 페이지와 페이지 모델을 추가하여 각각의 작업을 수행할 수 있습니다.
1. 데이터베이스 테이블 생성
먼저, AppointmentsTypes
테이블을 생성합니다. 이 테이블은 예약 종류의 이름과 활성화 여부, 만들어진 날짜 및 시간 등을 저장하는 테이블입니다. 예약 종류는 "Scheduled", "Completed", "Incomplete", "Canceled" 등과 같이 여러 종류가 있을 수 있습니다.
코드: AppointmentsTypes.sql
-- 예약 종류 관리를 위한 테이블
CREATE TABLE AppointmentsTypes (
Id INT PRIMARY KEY IDENTITY(1,1), -- 기본 키와 자동 증가 속성을 갖는 Id 컬럼
AppointmentTypeName NVARCHAR(50) NOT NULL, -- 예약 종류 이름을 저장하는 컬럼 (NOT NULL)
IsActive BIT NOT NULL DEFAULT 1, -- 예약 종류 활성화 여부를 나타내는 컬럼 (기본값: 1)
DateCreated DATETIME NOT NULL DEFAULT GETDATE() -- 레코드 생성 날짜 및 시간을 저장하는 컬럼 (기본값: 현재 날짜 및 시간)
)
2. 모델 클래스 생성
이제, AppointmentsTypes 테이블과 매핑되는 모델 클래스를 생성합니다. 예약 종류의 이름과 활성화 여부, 만들어진 날짜 및 시간 등의 정보를 저장할 수 있도록 클래스를 정의합니다.
코드: AppointmentType.cs
using System;
namespace VisualAcademy.Models
{
public class AppointmentsType
{
public int Id { get; set; }
public string AppointmentTypeName { get; set; }
public bool IsActive { get; set; }
public DateTime DateCreated { get; set; }
}
}
using System;
namespace VisualAcademy.Models
{
/// <summary>
/// AppointmentType 모델 클래스는 예약 종류를 나타냅니다.
/// </summary>
public class AppointmentsType
{
/// <summary>
/// 예약 종류의 고유 ID입니다.
/// </summary>
public int Id { get; set; }
/// <summary>
/// 예약 종류의 이름을 나타냅니다. 예: "Scheduled", "Completed", "Canceled" 등
/// </summary>
public string AppointmentTypeName { get; set; }
/// <summary>
/// 예약 종류가 활성화되었는지 여부를 나타냅니다. 활성화된 경우 true, 아닌 경우 false입니다.
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// 예약 종류가 생성된 날짜 및 시간입니다.
/// </summary>
public DateTime DateCreated { get; set; }
}
}
3. 리포지토리 클래스 생성
IAppointmentsTypeRepository 인터페이스와 이를 구현한 AppointmentsTypeRepository 클래스를 생성합니다. 이 리포지토리 클래스를 사용하여 데이터베이스에서 예약 종류를 가져오거나, 새로운 예약 종류를 추가하고, 수정 및 삭제할 수 있습니다.
코드: IAppointmentsTypeRepository.cs
public interface IAppointmentsTypeRepository
{
Task<IEnumerable<AppointmentsType>> GetAppointmentsTypesAsync();
Task<AppointmentsType> GetAppointmentsTypeByIdAsync(int id);
Task<bool> AddAppointmentsTypeAsync(AppointmentsType appointmentsType);
Task<bool> UpdateAppointmentsTypeAsync(AppointmentsType appointmentsType);
Task<bool> DeleteAppointmentsTypeAsync(int id);
}
코드: AppointmentsTypeRepository.cs
public class AppointmentsTypeRepository : IAppointmentsTypeRepository
{
// 코드 구현 (데이터베이스 연결 및 CRUD 작업)
}
Razor Pages에 직접 Repository 클래스 사용
마지막으로 Razor Pages에서 AppointmentsTypeRepository 클래스를 사용하여 데이터를 읽고 쓸 수 있는 페이지를 만듭니다. 각각의 CRUD 작업에 대응하는 Razor 페이지를 만들어 보겠습니다.
예를 들어, 예약 종류를 표시하는 페이지를 만들려면 Index.cshtml Razor 페이지를 생성하고, 해당 페이지 모델에서 IAppointmentsTypeRepository를 사용하여 데이터를 가져올 수 있습니다.
코드: Index.cshtml.cs
public class IndexModel : PageModel
{
private readonly IAppointmentsTypeRepository _appointmentsTypeRepository;
public IndexModel(IAppointmentsTypeRepository appointmentsTypeRepository)
{
_appointmentsTypeRepository = appointmentsTypeRepository;
}
public IEnumerable<AppointmentsType> AppointmentsTypes { get; set; }
public async Task OnGetAsync()
{
AppointmentsTypes = await _appointmentsTypeRepository.GetAppointmentsTypesAsync();
}
}
이와 같은 방법으로 추가, 수정 및 삭제 페이지를 만들어서 예약 종류를 관리하는 ASP.NET Core Razor Pages 애플리케이션을 완성할 수 있습니다.
4. 리포지토리 클래스 구현
코드: IAppointmentsTypeRepository.cs
public interface IAppointmentsTypeRepository
{
Task<IEnumerable<AppointmentsType>> GetAllAsync();
Task<AppointmentsType> GetByIdAsync(int id);
Task<bool> AddAsync(AppointmentsType model);
Task<bool> UpdateAsync(AppointmentsType model);
Task<bool> DeleteAsync(int id);
}
using System.Collections.Generic;
using System.Threading.Tasks;
using VisualAcademy.Models;
namespace VisualAcademy.Repositories
{
/// <summary>
/// IAppointmentsTypeRepository 인터페이스는 예약 종류 관련 데이터 액세스 작업을 정의합니다.
/// </summary>
public interface IAppointmentsTypeRepository
{
/// <summary>
/// 모든 예약 종류를 반환합니다.
/// </summary>
/// <returns>예약 종류 목록을 나타내는 비동기 작업</returns>
Task<IEnumerable<AppointmentsType>> GetAllAsync();
/// <summary>
/// 지정된 ID에 해당하는 예약 종류를 반환합니다.
/// </summary>
/// <param name="id">검색할 예약 종류의 ID입니다.</param>
/// <returns>예약 종류를 나타내는 비동기 작업</returns>
Task<AppointmentsType> GetByIdAsync(int id);
/// <summary>
/// 새로운 예약 종류를 추가합니다.
/// </summary>
/// <param name="model">추가할 예약 종류를 나타내는 AppointmentsType 객체입니다.</param>
/// <returns>작업이 성공적으로 완료되었는지 여부를 나타내는 비동기 작업</returns>
Task<bool> AddAsync(AppointmentsType model);
/// <summary>
/// 지정된 예약 종류를 업데이트합니다.
/// </summary>
/// <param name="model">업데이트할 예약 종류를 나타내는 AppointmentsType 객체입니다.</param>
/// <returns>작업이 성공적으로 완료되었는지 여부를 나타내는 비동기 작업</returns>
Task<bool> UpdateAsync(AppointmentsType model);
/// <summary>
/// 지정된 ID에 해당하는 예약 종류를 삭제합니다.
/// </summary>
/// <param name="id">삭제할 예약 종류의 ID입니다.</param>
/// <returns>작업이 성공적으로 완료되었는지 여부를 나타내는 비동기 작업</returns>
Task<bool> DeleteAsync(int id);
}
}
데이터베이스 연결 문자열을 전달받는 생성자를 가진 AppointmentsTypeRepository 클래스를 만들어 보겠습니다. 이 클래스는 IAppointmentsTypeRepository 인터페이스를 상속하고, Dapper를 사용하여 데이터베이스 작업을 수행합니다.
코드: AppointmentsTypeRepository.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using Dapper;
public class AppointmentsTypeRepository : IAppointmentsTypeRepository
{
private readonly string _connectionString;
public AppointmentsTypeRepository(string connectionString)
{
_connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
}
private IDbConnection Connection => new SqlConnection(_connectionString);
public async Task<IEnumerable<AppointmentsType>> GetAllAsync()
{
using (var connection = Connection)
{
const string query = "SELECT * FROM AppointmentsTypes";
return await connection.QueryAsync<AppointmentsType>(query);
}
}
public async Task<AppointmentsType> GetByIdAsync(int id)
{
using (var connection = Connection)
{
const string query = "SELECT * FROM AppointmentsTypes WHERE Id = @Id";
return await connection.QuerySingleOrDefaultAsync<AppointmentsType>(query, new { Id = id });
}
}
public async Task<bool> AddAsync(AppointmentsType model)
{
using (var connection = Connection)
{
const string query = "INSERT INTO AppointmentsTypes (AppointmentTypeName, IsActive, DateCreated) VALUES (@AppointmentTypeName, @IsActive, @DateCreated)";
return await connection.ExecuteAsync(query, model) > 0;
}
}
public async Task<bool> UpdateAsync(AppointmentsType model)
{
using (var connection = Connection)
{
const string query = "UPDATE AppointmentsTypes SET AppointmentTypeName = @AppointmentTypeName, IsActive = @IsActive WHERE Id = @Id";
return await connection.ExecuteAsync(query, model) > 0;
}
}
public async Task<bool> DeleteAsync(int id)
{
using (var connection = Connection)
{
const string query = "DELETE FROM AppointmentsTypes WHERE Id = @Id";
return await connection.ExecuteAsync(query, new { Id = id }) > 0;
}
}
}
다음 코드는 실제 프로그래밍 업무에서 사용한 주석문이 포함된 코드입니다.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using Dapper;
/// <summary>
/// AppointmentsTypeRepository 클래스는 IAppointmentsTypeRepository 인터페이스를 구현하여 예약 종류 관련 데이터 액세스 작업을 처리합니다.
/// </summary>
public class AppointmentsTypeRepository : IAppointmentsTypeRepository
{
private readonly string _connectionString;
/// <summary>
/// AppointmentsTypeRepository 클래스의 생성자입니다. 데이터베이스 연결 문자열을 전달받습니다.
/// </summary>
/// <param name="connectionString">데이터베이스 연결 문자열입니다.</param>
public AppointmentsTypeRepository(string connectionString)
{
_connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
}
private IDbConnection Connection => new SqlConnection(_connectionString);
/// <inheritdoc/>
public async Task<IEnumerable<AppointmentsType>> GetAllAsync()
{
using (var connection = Connection)
{
const string query = "SELECT * FROM AppointmentsTypes";
return await connection.QueryAsync<AppointmentsType>(query);
}
}
/// <inheritdoc/>
public async Task<AppointmentsType> GetByIdAsync(int id)
{
using (var connection = Connection)
{
const string query = "SELECT * FROM AppointmentsTypes WHERE Id = @Id";
return await connection.QuerySingleOrDefaultAsync<AppointmentsType>(query, new { Id = id });
}
}
/// <inheritdoc/>
public async Task<bool> AddAsync(AppointmentsType model)
{
using (var connection = Connection)
{
const string query = "INSERT INTO AppointmentsTypes (AppointmentTypeName, IsActive, DateCreated) VALUES (@AppointmentTypeName, @IsActive, @DateCreated)";
return await connection.ExecuteAsync(query, model) > 0;
}
}
/// <inheritdoc/>
public async Task<bool> UpdateAsync(AppointmentsType model)
{
using (var connection = Connection)
{
const string query = "UPDATE AppointmentsTypes SET AppointmentTypeName = @AppointmentTypeName, IsActive = @IsActive WHERE Id = @Id";
return await connection.ExecuteAsync(query, model) > 0;
}
}
/// <inheritdoc/>
public async Task<bool> DeleteAsync(int id)
{
using (var connection = Connection)
{
const string query = "DELETE FROM AppointmentsTypes WHERE Id = @Id";
return await connection.ExecuteAsync(query, new { Id = id }) > 0;
}
}
}
이제 AppointmentsTypeRepository 클래스가 IAppointmentsTypeRepository 인터페이스를 상속하고, 생성자에서 데이터베이스 연결 문자열을 전달받습니다. 또한, Dapper를 사용하여 각 메서드에서 데이터베이스 작업을 수행합니다.
5. CRUD 구현
Pages 폴더에 Appointments 폴더를 만들고, 그 안에 AppointmentsTypes 폴더를 만듭니다. 이제 AppointmentsTypes 폴더에 5개의 cshtml 파일을 추가하겠습니다. 각 파일은 다음과 같은 기능을 수행합니다:
- Index.cshtml - 예약 종류 목록을 표시합니다.
- Create.cshtml - 새 예약 종류를 생성합니다.
- Edit.cshtml - 기존 예약 종류를 수정합니다.
- Delete.cshtml - 예약 종류를 삭제합니다.
- Details.cshtml - 예약 종류의 세부 정보를 표시합니다.
각 cshtml 파일에 해당하는 페이지 모델도 생성해야 합니다. 페이지 모델의 이름은 {페이지 이름}Model 형식으로 지어집니다. 예를 들어, Index.cshtml의 페이지 모델은 IndexModel이라는 이름을 갖습니다.
Index.cshtml
다음은 Index.cshtml 및 Index.cshtml.cs 파일의 소스 코드입니다.
코드: Index.cshtml.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
using VisualAcademy.Models;
namespace VisualAcademy.Pages.Appointments.AppointmentsTypes
{
public class IndexModel : PageModel
{
private readonly IAppointmentsTypeRepository _repository;
public IndexModel(IAppointmentsTypeRepository repository)
{
_repository = repository;
}
public IEnumerable<AppointmentsType> AppointmentsTypes { get; set; }
public async Task OnGetAsync()
{
AppointmentsTypes = await _repository.GetAllAsync();
}
}
}
코드: Index.cshtml
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.IndexModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Appointments Types - VisualAcademy</title>
</head>
<body>
<h1>Appointments Types</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Type</th>
<th>Active</th>
<th>Date Created</th>
</tr>
</thead>
<tbody>
@foreach (var appointmentsType in Model.AppointmentsTypes)
{
<tr>
<td>@appointmentsType.Id</td>
<td>@appointmentsType.AppointmentTypeName</td>
<td>@(appointmentsType.IsActive ? "Yes" : "No")</td>
<td>@appointmentsType.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")</td>
</tr>
}
</tbody>
</table>
</body>
</html>
부트스트랩을 적용한 코드는 다음과 같습니다.
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.IndexModel
@{
ViewData["Title"] = "Appointments Types";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
<title>Appointments Types - VisualAcademy</title>
</head>
<body>
<div class="container">
<h1 class="mt-4 mb-4">Appointments Types</h1>
<a class="btn btn-primary mb-4" href="./Create">Add New Appointment Type</a>
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Type</th>
<th>Active</th>
<th>Date Created</th>
</tr>
</thead>
<tbody>
@foreach (var appointmentsType in Model.AppointmentsTypes)
{
<tr>
<td>@appointmentsType.Id</td>
<td>@appointmentsType.AppointmentTypeName</td>
<td>@(appointmentsType.IsActive ? "Yes" : "No")</td>
<td>@appointmentsType.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")</td>
</tr>
}
</tbody>
</table>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
</body>
</html>
수정과 삭제 버튼을 추가해서 이 두 가지 기능을 더 만들겠습니다.
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.IndexModel
@{
ViewData["Title"] = "Appointments Types";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
<title>Appointments Types - VisualAcademy</title>
</head>
<body>
<div class="container">
<h1 class="mt-4 mb-4">Appointments Types</h1>
<a class="btn btn-primary mb-4" href="/Appointments/AppointmentsTypes/Create">Add New Appointment Type</a>
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Type</th>
<th>Active</th>
<th>Date Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var appointmentsType in Model.AppointmentsTypes)
{
<tr>
<td>@appointmentsType.Id</td>
<td>@appointmentsType.AppointmentTypeName</td>
<td>@(appointmentsType.IsActive ? "Yes" : "No")</td>
<td>@appointmentsType.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")</td>
<td>
<a class="btn btn-secondary" href="/Appointments/AppointmentsTypes/Edit?id=@appointmentsType.Id">Edit</a>
<a class="btn btn-danger" href="/Appointments/AppointmentsTypes/Delete?id=@appointmentsType.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
</body>
</html>
이제 Index.cshtml 페이지에서 예약 종류 목록을 표시할 수 있습니다. 페이지 모델인 IndexModel에서 IAppointmentsTypeRepository 인터페이스를 주입하고, OnGetAsync 메서드에서 GetAllAsync 메서드를 호출하여 예약 종류를 가져옵니다. Index.cshtml 파일에서 Razor 구문을 사용하여 Model.AppointmentsTypes 속성을 순회하며 테이블에 예약 종류를 표시합니다.
Create.cshtml
다음은 Create.cshtml 및 Create.cshtml.cs 파일의 소스 코드입니다.
코드: Create.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using VisualAcademy.Models;
namespace VisualAcademy.Pages.Appointments.AppointmentsTypes
{
public class CreateModel : PageModel
{
private readonly IAppointmentsTypeRepository _repository;
public CreateModel(IAppointmentsTypeRepository repository)
{
_repository = repository;
}
[BindProperty]
public AppointmentsType AppointmentsType { get; set; }
public IActionResult OnGet()
{
AppointmentsType = new();
AppointmentsType.IsActive = true; // 체크박스는 체크된 상태로
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
AppointmentsType.DateCreated = DateTime.Now; // 현재 시간 추가
if (!ModelState.IsValid)
{
return Page();
}
await _repository.AddAsync(AppointmentsType);
return RedirectToPage("./Index");
}
}
}
코드: Create.cshtml
학습용 심플 버전은 다음과 같습니다.
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.CreateModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Create Appointment Type - VisualAcademy</title>
</head>
<body>
<h1>Create Appointment Type</h1>
<form method="post">
<div>
<label for="AppointmentTypeName">Type:</label>
<input asp-for="AppointmentsType.AppointmentTypeName" id="AppointmentTypeName" />
<span asp-validation-for="AppointmentsType.AppointmentTypeName"></span>
</div>
<div>
<label for="IsActive">Active:</label>
<input asp-for="AppointmentsType.IsActive" id="IsActive" type="checkbox" />
</div>
<button type="submit">Create</button>
</form>
</body>
</html>
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.CreateModel
@{
ViewData["Title"] = "Create Appointment Type";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
<title>Create Appointment Type - VisualAcademy</title>
</head>
<body>
<div class="container">
<h1 class="mt-4 mb-4">Create Appointment Type</h1>
<form method="post">
<div class="mb-3">
<label for="AppointmentTypeName" class="form-label">Type:</label>
<input asp-for="AppointmentsType.AppointmentTypeName" id="AppointmentTypeName" class="form-control" />
<span asp-validation-for="AppointmentsType.AppointmentTypeName" class="text-danger"></span>
</div>
<div class="mb-3 form-check">
<input asp-for="AppointmentsType.IsActive" id="IsActive" type="checkbox" class="form-check-input" />
<label for="IsActive" class="form-check-label">Active:</label>
</div>
<button type="submit" class="btn btn-primary">Create</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@@popperjs/core@@2.9.3/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
</body>
</html>
Create.cshtml 페이지를 사용하여 새로운 예약 종류를 생성할 수 있습니다. 페이지 모델인 CreateModel에서 IAppointmentsTypeRepository 인터페이스를 주입하고, OnPostAsync 메서드에서 AddAsync 메서드를 호출하여 예약 종류를 추가합니다. Create.cshtml 파일에서 Razor 구문과 HTML을 사용하여 예약 종류의 폼을 만듭니다. 폼을 제출하면 OnPostAsync 메서드가 호출되어 새로운 예약 종류가 데이터베이스에 추가되고, 사용자가 Index 페이지로 리디렉션됩니다.
Edit.cshtml
다음은 Edit.cshtml 및 Edit.cshtml.cs 파일의 소스 코드입니다.
코드: Edit.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using VisualAcademy.Models;
namespace VisualAcademy.Pages.Appointments.AppointmentsTypes
{
public class EditModel : PageModel
{
private readonly IAppointmentsTypeRepository _repository;
public EditModel(IAppointmentsTypeRepository repository)
{
_repository = repository;
}
[BindProperty]
public AppointmentsType AppointmentsType { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
AppointmentsType = await _repository.GetByIdAsync(id.Value);
if (AppointmentsType == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
await _repository.UpdateAsync(AppointmentsType);
return RedirectToPage("./Index");
}
}
}
코드: Edit.cshtml
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.EditModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Edit Appointment Type - VisualAcademy</title>
</head>
<body>
<h1>Edit Appointment Type</h1>
<form method="post">
<input type="hidden" asp-for="AppointmentsType.Id" />
<div>
<label for="AppointmentTypeName">Type:</label>
<input asp-for="AppointmentsType.AppointmentTypeName" id="AppointmentTypeName" />
<span asp-validation-for="AppointmentsType.AppointmentTypeName"></span>
</div>
<div>
<label for="IsActive">Active:</label>
<input asp-for="AppointmentsType.IsActive" id="IsActive" type="checkbox" />
</div>
<button type="submit">Save</button>
</form>
</body>
</html>
Edit.cshtml 페이지를 사용하여 예약 종류를 편집할 수 있습니다. 페이지 모델인 EditModel에서 IAppointmentsTypeRepository 인터페이스를 주입하고, OnGetAsync 메서드에서 GetByIdAsync 메서드를 호출하여 편집할 예약 종류의 세부 정보를 가져옵니다. Edit.cshtml 파일에서 Razor 구문과 HTML을 사용하여 예약 종류의 폼을 만듭니다. 폼을 제출하면 OnPostAsync 메서드가 호출되어 예약 종류가 데이터베이스에 업데이트되고, 사용자가 Index 페이지로 리디렉션됩니다.
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.EditModel
@{
ViewData["Title"] = "Edit Appointment Type";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
<title>Edit Appointment Type - VisualAcademy</title>
</head>
<body>
<div class="container">
<h1 class="mt-4 mb-4">Edit Appointment Type</h1>
<form method="post">
<input type="hidden" asp-for="AppointmentsType.Id" />
<div class="mb-3">
<label for="AppointmentTypeName" class="form-label">Type:</label>
<input asp-for="AppointmentsType.AppointmentTypeName" id="AppointmentTypeName" class="form-control" />
<span asp-validation-for="AppointmentsType.AppointmentTypeName" class="text-danger"></span>
</div>
<div class="mb-3 form-check">
<input asp-for="AppointmentsType.IsActive" id="IsActive" type="checkbox" class="form-check-input" />
<label for="IsActive" class="form-check-label">Active:</label>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
</body>
</html>
Delete.cshtml
다음은 Delete.cshtml 및 Delete.cshtml.cs 파일의 소스 코드입니다.
코드: Delete.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using VisualAcademy.Models;
namespace VisualAcademy.Pages.Appointments.AppointmentsTypes
{
public class DeleteModel : PageModel
{
private readonly IAppointmentsTypeRepository _repository;
public DeleteModel(IAppointmentsTypeRepository repository)
{
_repository = repository;
}
[BindProperty]
public AppointmentsType AppointmentsType { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
AppointmentsType = await _repository.GetByIdAsync(id.Value);
if (AppointmentsType == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync(int? id)
{
if (id == null)
{
return NotFound();
}
await _repository.DeleteAsync(id.Value);
return RedirectToPage("./Index");
}
}
}
코드: Delete.cshtml
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.DeleteModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Delete Appointment Type - VisualAcademy</title>
</head>
<body>
<h1>Delete Appointment Type</h1>
<p>Are you sure you want to delete this appointment type?</p>
<dl>
<dt>Type</dt>
<dd>@Model.AppointmentsType.AppointmentTypeName</dd>
<dt>Active</dt>
<dd>@(Model.AppointmentsType.IsActive ? "Yes" : "No")</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="AppointmentsType.Id" />
<button type="submit">Delete</button>
</form>
</body>
</html>
Delete.cshtml 페이지를 사용하여 예약 종류를 삭제할 수 있습니다. 페이지 모델인 DeleteModel에서 IAppointmentsTypeRepository 인터페이스를 주입하고, OnGetAsync 메서드에서 GetByIdAsync 메서드를 호출하여 삭제할 예약 종류의 세부 정보를 가져옵니다. Delete.cshtml 파일에서 Razor 구문과 HTML을 사용하여 예약 종류의 세부 정보를 표시하고 삭제 확인 메시지를 표시합니다. 확인 버튼을 클릭하면 OnPostAsync 메서드가 호출되어 예약 종류가 데이터베이스에서 삭제되고, 사용자가 Index 페이지로 리디렉션됩니다.
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.DeleteModel
@{
ViewData["Title"] = "Delete Appointment Type";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
<title>Delete Appointment Type - VisualAcademy</title>
</head>
<body>
<div class="container">
<h1 class="mt-4 mb-4">Delete Appointment Type</h1>
<p>Are you sure you want to delete this appointment type?</p>
<dl class="row">
<dt class="col-sm-2">Type</dt>
<dd class="col-sm-10">@Model.AppointmentsType.AppointmentTypeName</dd>
<dt class="col-sm-2">Active</dt>
<dd class="col-sm-10">@(Model.AppointmentsType.IsActive ? "Yes" : "No")</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="AppointmentsType.Id" />
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
</body>
</html>
Details.cshtml
다음은 Details.cshtml 및 Details.cshtml.cs 파일의 소스 코드입니다.
코드: Details.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using VisualAcademy.Models;
namespace VisualAcademy.Pages.Appointments.AppointmentsTypes
{
public class DetailsModel : PageModel
{
private readonly IAppointmentsTypeRepository _repository;
public DetailsModel(IAppointmentsTypeRepository repository)
{
_repository = repository;
}
public AppointmentsType AppointmentsType { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
AppointmentsType = await _repository.GetByIdAsync(id.Value);
if (AppointmentsType == null)
{
return NotFound();
}
return Page();
}
}
}
코드: Details.cshtml
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.DetailsModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Appointment Type Details - VisualAcademy</title>
</head>
<body>
<h1>Appointment Type Details</h1>
<dl>
<dt>Id</dt>
<dd>@Model.AppointmentsType.Id</dd>
<dt>Type</dt>
<dd>@Model.AppointmentsType.AppointmentTypeName</dd>
<dt>Active</dt>
<dd>@(Model.AppointmentsType.IsActive ? "Yes" : "No")</dd>
<dt>Date Created</dt>
<dd>@Model.AppointmentsType.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")</dd>
</dl>
</body>
</html>
Details.cshtml 페이지를 사용하여 예약 종류의 세부 정보를 표시할 수 있습니다. 페이지 모델인 DetailsModel에서 IAppointmentsTypeRepository 인터페이스를 주입하고, OnGetAsync 메서드에서 GetByIdAsync 메서드를 호출하여 예약 종류의 세부 정보를 가져옵니다. Details.cshtml 파일에서 Razor 구문과 HTML을 사용하여 예약 종류의 세부 정보를 표시합니다. 세부 정보 페이지는 읽기 전용이므로 추가 작업을 수행할 필요가 없습니다.
@page
@model VisualAcademy.Pages.Appointments.AppointmentsTypes.DetailsModel
@{
ViewData["Title"] = "Appointment Type Details";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
<title>Appointment Type Details - VisualAcademy</title>
</head>
<body>
<div class="container">
<h1 class="mt-4 mb-4">Appointment Type Details</h1>
<dl class="row">
<dt class="col-sm-2">Id</dt>
<dd class="col-sm-10">@Model.AppointmentsType.Id</dd>
<dt class="col-sm-2">Type</dt>
<dd class="col-sm-10">@Model.AppointmentsType.AppointmentTypeName</dd>
<dt class="col-sm-2">Active</dt>
<dd class="col-sm-10">@(Model.AppointmentsType.IsActive ? "Yes" : "No")</dd>
<dt class="col-sm-2">Date Created</dt>
<dd class="col-sm-10">@Model.AppointmentsType.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")</dd>
</dl>
<div class="mt-3">
<a href="./" class="btn btn-secondary">List</a>
<a href="./Edit/@Model.AppointmentsType.Id" class="btn btn-primary">Edit</a>
<a href="./Delete/@Model.AppointmentsType.Id" class="btn btn-danger">Delete</a>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
</body>
</html>
마무리
ASP.NET Core Razor Pages에서 인증된 사용자만 특정 페이지에 접근하게 하려면 Authorize 특성을 사용하여 해당 페이지의 PageModel 클래스에 적용해야 합니다.
먼저, 프로젝트에 Microsoft.AspNetCore.Authorization 네임스페이스를 사용하도록 설정하세요.
Index.cshtml.cs 파일에 Authorize 특성을 적용하려면 다음과 같이 코드를 수정해주세요.
코드: Index.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using VisualAcademy.Models;
using VisualAcademy.Services;
namespace VisualAcademy.Pages.Appointments.AppointmentsTypes
{
[Authorize] // <- 이 부분을 추가하세요.
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
private readonly IAppointmentsTypeRepository _appointmentsTypeRepository;
public IndexModel(ILogger<IndexModel> logger, IAppointmentsTypeRepository appointmentsTypeRepository)
{
_logger = logger;
_appointmentsTypeRepository = appointmentsTypeRepository;
}
public IList<AppointmentsType> AppointmentsTypes { get; set; }
public async Task OnGetAsync()
{
AppointmentsTypes = (await _appointmentsTypeRepository.GetAllAsync()).ToList();
}
}
}
위 코드에서는 Authorize 특성을 PageModel 클래스에 추가하여 인증된 사용자만 이 페이지에 접근할 수 있도록 합니다. 인증되지 않은 사용자가 이 페이지에 접근하려고 시도하면 로그인 페이지로 리디렉션됩니다.
참고: 이 작업을 수행하려면 프로젝트에서 이미 인증 및 권한 부여를 구성해야 합니다. 이렇게 하지 않으면 페이지에 대한 접근이 제한되거나 제대로 작동하지 않을 수 있습니다.
6. Web API 컨트롤러 클래스
다음은 예약 종류에 대한 CRUD 작업을 수행하는 ASP.NET Core Web API 컨트롤러 클래스입니다.
코드: AppointmentsTypesController.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using VisualAcademy.Models;
namespace VisualAcademy.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AppointmentsTypesController : ControllerBase
{
private readonly IAppointmentsTypeRepository _repository;
public AppointmentsTypesController(IAppointmentsTypeRepository repository)
{
_repository = repository;
}
// GET: api/AppointmentsTypes
[HttpGet]
public async Task<IEnumerable<AppointmentsType>> GetAppointmentsTypes()
{
return await _repository.GetAllAsync();
}
// GET: api/AppointmentsTypes/5
[HttpGet("{id}")]
public async Task<ActionResult<AppointmentsType>> GetAppointmentsType(int id)
{
var appointmentsType = await _repository.GetByIdAsync(id);
if (appointmentsType == null)
{
return NotFound();
}
return appointmentsType;
}
// PUT: api/AppointmentsTypes/5
[HttpPut("{id}")]
public async Task<IActionResult> UpdateAppointmentsType(int id, AppointmentsType appointmentsType)
{
if (id != appointmentsType.Id)
{
return BadRequest();
}
await _repository.UpdateAsync(appointmentsType);
return NoContent();
}
// POST: api/AppointmentsTypes
[HttpPost]
public async Task<ActionResult<AppointmentsType>> CreateAppointmentsType(AppointmentsType appointmentsType)
{
appointmentsType.DateCreated = DateTime.Now; // 현재 시간 추가
await _repository.AddAsync(appointmentsType);
return CreatedAtAction("GetAppointmentsType", new { id = appointmentsType.Id }, appointmentsType);
}
// DELETE: api/AppointmentsTypes/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteAppointmentsType(int id)
{
var appointmentsType = await _repository.GetByIdAsync(id);
if (appointmentsType == null)
{
return NotFound();
}
await _repository.DeleteAsync(id);
return NoContent();
}
}
}
이 컨트롤러 클래스에서는 IAppointmentsTypeRepository 인터페이스를 주입하고, HttpGet, HttpPut, HttpPost, HttpDelete와 같은 HTTP 동사를 사용하여 CRUD 작업을 수행합니다. 이를 통해 API 호출을 통해 예약 종류 데이터를 가져오고, 생성하고, 업데이트하고, 삭제할 수 있습니다.
이제 프로젝트에 필요한 모든 클래스를 추가하였으므로, Startup.cs 파일에서 의존성 주입을 설정하고, 필요한 경우 데이터베이스 및 테이블을 생성하여 프로젝트를 실행할 수 있습니다.
7. jQuery CRUD 테스트
jQuery를 사용하여 Create 및 List를 구현하는 내용입니다.
아래에는 AppointmentsTypesController의 CRUD 작업을 테스트할 수 있는 간단한 jQuery를 사용한 HTML 문서가 있습니다.
코드: AppointmentsTypesTest.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Appointments Types Test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h1>Appointments Types Test</h1>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Active</th>
<th>Created</th>
</tr>
</thead>
<tbody id="appointmentsTypesBody">
</tbody>
</table>
<button id="refreshButton" class="btn btn-primary">Refresh</button>
<hr>
<h2>Add Appointment Type</h2>
<form id="createAppointmentTypeForm">
<div class="form-group">
<label for="appointmentTypeName">Name:</label>
<input type="text" class="form-control" id="appointmentTypeName" required>
</div>
<div class="form-group">
<label for="isActive">Active:</label>
<input type="checkbox" class="form-control" id="isActive">
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
</div>
<script>
const apiUrl = "http://localhost:5000/api/AppointmentsTypes";
$(document).ready(function () {
loadAppointmentsTypes();
$("#refreshButton").click(function () {
loadAppointmentsTypes();
});
$("#createAppointmentTypeForm").submit(function (event) {
event.preventDefault();
createAppointmentType();
});
});
function loadAppointmentsTypes() {
$.getJSON(apiUrl, function (data) {
let appointmentsTypes = $("#appointmentsTypesBody");
appointmentsTypes.empty();
$.each(data, function (key, value) {
let active = value.isActive ? "Yes" : "No";
appointmentsTypes.append(`<tr>
<td>${value.id}</td>
<td>${value.appointmentTypeName}</td>
<td>${active}</td>
<td>${value.dateCreated}</td>
</tr>`);
});
});
}
function createAppointmentType() {
let appointmentTypeName = $("#appointmentTypeName").val();
let isActive = $("#isActive").is(":checked");
$.ajax({
url: apiUrl,
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"appointmentTypeName": appointmentTypeName,
"isActive": isActive
}),
success: function () {
alert("Appointment type created.");
loadAppointmentsTypes();
$("#createAppointmentTypeForm")[0].reset();
},
error: function () {
alert("An error occurred while creating the appointment type.");
}
});
}
</script>
</body>
</html>
아래에는 AppointmentsTypesController의 GetAll Web API를 호출하여 예약 종류 리스트를 HTML 드롭다운 리스트로 출력하는 jQuery 예제가 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Appointments Types Dropdown</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h1>Appointments Types Dropdown</h1>
<select class="form-control" id="appointmentsTypesDropdown">
</select>
</div>
<script>
const apiUrl = "http://localhost:5000/api/AppointmentsTypes";
$(document).ready(function () {
loadAppointmentsTypesDropdown();
});
function loadAppointmentsTypesDropdown() {
$.getJSON(apiUrl, function (data) {
let appointmentsTypesDropdown = $("#appointmentsTypesDropdown");
appointmentsTypesDropdown.empty();
$.each(data, function (key, value) {
appointmentsTypesDropdown.append(`<option value="${value.id}">${value.appointmentTypeName}</option>`);
});
});
}
</script>
</body>
</html>
이 예제는 AppointmentsTypesController의 GetAll Web API를 호출하여 모든 예약 종류를 가져온 다음, 이를 HTML 드롭다운 리스트로 출력합니다. 페이지가 로드되면 loadAppointmentsTypesDropdown() 함수가 실행되어 예약 종류 목록을 가져옵니다.
아래 코드는 AppointmentTypeId를 지정하면 드롭다운리스트 항목의 해당 항목이 선택된 상태로 표시되게 하는 기능을 추가한 예제입니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Appointments Types Dropdown</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h1>Appointments Types Dropdown</h1>
<select class="form-control" id="appointmentsTypesDropdown">
</select>
</div>
<script>
const apiUrl = "http://localhost:5000/api/AppointmentsTypes";
const appointmentTypeId = 2; // 지정된 AppointmentTypeId
$(document).ready(function () {
loadAppointmentsTypesDropdown();
});
function loadAppointmentsTypesDropdown() {
$.getJSON(apiUrl, function (data) {
let appointmentsTypesDropdown = $("#appointmentsTypesDropdown");
appointmentsTypesDropdown.empty();
$.each(data, function (key, value) {
let selected = value.id === appointmentTypeId ? "selected" : "";
appointmentsTypesDropdown.append(`<option value="${value.id}" ${selected}>${value.appointmentTypeName}</option>`);
});
});
}
</script>
</body>
</html>
appointmentTypeId 변수를 사용하여 지정된 AppointmentTypeId를 정의합니다. 이후 loadAppointmentsTypesDropdown() 함수에서 각 드롭다운 항목을 생성할 때, appointmentTypeId와 일치하는 항목에 selected 속성을 추가하여 해당 항목이 선택된 상태로 표시되게 합니다. 이 예제에서는 appointmentTypeId를 2로 지정했습니다. 이에 따라 id가 2인 항목이 선택된 상태로 표시됩니다.