ASP.NET Core MVC모델을 이용해서 게시판 만들기 (4) Views, Models 폴더
우선 Views 폴더부터 살펴 보겠습니다.
views폴더 안에 Main폴더가 있고 그 안에 이제 페이지들이 들어가야 합니다.
글 작성할 PostPage.cshtml파일과 글목록을 확인할 ListPage.cshtml파일이 존재합니다.
PostPage
@model noticeboard.Models.Noticeboard
@{
ViewData["Title"] = "PostPage";
}
<div class="Main-container">
<h2 class="h2">새 게시글 작성</h2>
<div class="container">
<form asp-action="PostPage" method="post" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<div class="form-group">
<label asp-for="Title" class="label">제목</label>
<input asp-for="Title" class="input" />
<span asp-validation-for="Title" class="text"></span>
</div>
<div class="form-group">
<label asp-for="Content" class="label">내용</label>
<textarea asp-for="Content" class="textarea"></textarea>
<span asp-validation-for="Content" class="text"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="label">작성자</label>
<input asp-for="Author" class="input" />
<span asp-validation-for="Author" class="text"></span>
</div>
<div class="form-group">
<label class="label">파일 업로드 (필수 사항)</label>
<input class="input" type="file" name="uploadedFile" />
<span asp-validation-for="Filepath" class="text"></span>
</div>
<button type="submit" class="">작성</button>
</form>
</div>
</div>
@model noticeboard.Models.Noticeboard
이 라인은 이 뷰가 Noticeboard 모델을 사용한다고 선언합니다.
이 모델은 게시글 작성에 필요한 데이터를 담고 있을 것입니다.
models폴더안에 Noticeboard.cs 파일이 존재합니다 마찬가지로 게시글 작성에 필요한 데이터들이 존재합니다.
Noticeboard.cs
using System;
using System.ComponentModel.DataAnnotations;
namespace noticeboard.Models
{
public class Noticeboard
{
public int Id { get; set; }
[Required(ErrorMessage = "제목을 입력하세요.")]
[StringLength(100, MinimumLength = 1, ErrorMessage = "제목은 1자 이상이어야 합니다.")]
public string Title { get; set; }
[Required(ErrorMessage = "내용을 입력하세요.")]
[StringLength(500, MinimumLength = 1, ErrorMessage = "내용은 1자 이상이어야 합니다.")]
public string Content { get; set; }
public string? Filepath { get; set; }
public string? Filename { get; set; }
[Required(ErrorMessage = "작성자를 입력하세요.")]
[StringLength(20, ErrorMessage = "작성자는 20자 이하이어야 합니다.")]
public string Author { get; set; }
public DateTime Date { get; set; } = DateTime.Now;
public int Views { get; set; }
}
}
이어서 코드 분석을 하겠습니다.
@{ ViewData["Title"] = "PostPage"; }
이 부분은 뷰의 제목을 "PostPage"로 설정합니다.
ViewData는 컨트롤러에서 뷰로 데이터를 전달할 때 사용되는 사전(dictionary)입니다.
<form asp-action="PostPage" method="post" enctype="multipart/form-data">
이 부분은 폼 태그를 정의합니다.
asp-action="PostPage": 폼이 제출되었을 때 데이터를 처리할 액션 메서드가 PostPage임을 나타냅니다.
method="post": 폼 데이터를 POST 메서드로 제출함을 나타냅니다.
enctype="multipart/form-data": 파일 업로드를 허용하는 인코딩 타입을 설정합니다.
asp-action 속성은 ASP.NET Core MVC에서 폼이 제출될 때 요청이 처리될 컨트롤러의 액션 메서드를 지정하는 데 사용됩니다. 이를 통해 사용자가 폼을 제출할 때 해당 데이터를 처리할 특정 메서드로 요청이 전송됩니다.
enctype="multipart/form-data" 속성은 HTML 폼에서 파일 업로드를 처리하기 위해 사용되는 속성입니다.
@Html.AntiForgeryToken()
이 부분은 CSRF(Cross-Site Request Forgery) 공격을 방지하기 위해 사용됩니다.
폼 제출 시 검증을 위한 토큰이 추가됩니다.
다음은 ListPage.cshtml입니다.
ListPage
@model IEnumerable<noticeboard.Models.Noticeboard>
@{
ViewData["Title"] = "ListPage";
}
<div class="Main-container">
<h2 class="h2">게시글 목록</h2>
@if (Model == null || !Model.Any())
{
<p>게시글이 없습니다.</p>
}
else
{
<table class="table">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>첨부파일</th>
<th>등록일</th>
<th>등록자</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
@foreach (var post in Model)
{
<tr>
<td>@post.Id</td>
<td>@Html.ActionLink(post.Title, "Details", new { id = post.Id })</td>
<td>
@if (!string.IsNullOrEmpty(post.Filepath))
{
<a href="@Url.Action("DownloadFile", "Main", new { filePath = post.Filepath, fileName = post.Filename })">첨부파일</a>
}
</td>
<td>@post.Date.ToShortDateString()</td>
<td>@post.Author</td>
<td>@post.Views</td>
</tr>
}
</tbody>
</table>
}
</div>
@model IEnumerable<noticeboard.Models.Noticeboard>
이 라인은 이 뷰가 Noticeboard 모델의 목록을 사용한다고 선언합니다. IEnumerable은 제네릭 인터페이스로,
Noticeboard 모델 객체의 컬렉션을 나타냅니다.
이 라인은 이 뷰가 여러 개의 Noticeboard 모델 객체를 사용한다고 선언하는 것입니다.
쉽게 설명하면
@model 키워드:이 키워드는 이 뷰에서 사용할 데이터 유형을 지정합니다.
IEnumerable<noticeboard.Models.Noticeboard>
- IEnumerable<T>는 제네릭 인터페이스로, 여러 개의 데이터를 담을 수 있는 목록을 나타냅니다.여기서 T는 - - noticeboard.Models.Noticeboard 타입입니다. 즉, Noticeboard 모델의 객체들을 담을 수 있는 목록을 의미합니다.
@{ ViewData["Title"] = "ListPage"; }
이 부분은 뷰의 제목을 "ListPage"로 설정합니다. ViewData는 컨트롤러에서 뷰로 데이터를 전달할 때 사용되는 사전(dictionary)입니다.
<tbody>
@foreach (var post in Model)
{
<tr>
<td>@post.Id</td>
<td>@Html.ActionLink(post.Title, "Details", new { id = post.Id })</td>
<td>
@if (!string.IsNullOrEmpty(post.Filepath))
{
<a href="@Url.Action("DownloadFile", "Main", new { filePath = post.Filepath, fileName = post.Filename })">첨부파일</a>
}
</td>
<td>@post.Date.ToShortDateString()</td>
<td>@post.Author</td>
<td>@post.Views</td>
</tr>
}
</tbody>
@foreach (var post in Model): 모델의 각 게시글에 대해 반복문을 돌며 행을 생성합니다.
@post.Id: 게시글의 ID를 표시합니다.
@Html.ActionLink(post.Title, "Details", new { id = post.Id }): 게시글 제목을 링크로 표시하며, 클릭 시 Details 액션 메서드로 이동하여 해당 게시글의 세부 정보를 표시합니다.
@if (!string.IsNullOrEmpty(post.Filepath)) { ... }: 게시글에 첨부파일이 있는 경우, 파일 링크를 표시합니다. DownloadFile 액션을 호출하여 파일을 다운로드합니다.
@post.Date.ToShortDateString(): 게시글 등록 날짜를 간략한 형식으로 표시합니다.
@post.Author: 게시글 작성자를 표시합니다.
@post.Views: 게시글 조회수를 표시합니다.