728x90
반응형
728x170
▶ Models/Movie.cs
using System;
using System.ComponentModel.DataAnnotations;
namespace TestProject.Models
{
/// <summary>
/// 영화
/// </summary>
public class Movie
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region ID - ID
/// <summary>
/// ID
/// </summary>
public int ID { get; set; }
#endregion
#region 제목 - Title
/// <summary>
/// 제목
/// </summary>
public string Title { get; set; }
#endregion
#region 릴리즈 일자 - ReleaseDate
/// <summary>
/// 릴리즈 일자
/// </summary>
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
#endregion
#region 장르 - Genre
/// <summary>
/// 장르
/// </summary>
public string Genre { get; set; }
#endregion
#region 가격 - Price
/// <summary>
/// 가격
/// </summary>
public decimal Price { get; set; }
#endregion
}
}
728x90
▶ Data/DatabaseContext.cs
using Microsoft.EntityFrameworkCore;
using TestProject.Models;
namespace TestProject.Data
{
/// <summary>
/// 데이터베이스 컨텍스트
/// </summary>
public class DatabaseContext : DbContext
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 영화 - Movie
/// <summary>
/// 영화
/// </summary>
public DbSet<Movie> Movie { get; set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DatabaseContext(options)
/// <summary>
/// 생성자
/// </summary>
/// <param name="options">옵션</param>
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
}
#endregion
}
}
300x250
▶ appsettings.json
{
"Logging" :
{
"LogLevel" :
{
"Default" : "Information",
"Microsoft" : "Warning",
"Microsoft.Hosting.Lifetime" : "Information"
}
},
"AllowedHosts" : "*",
"ConnectionStrings" :
{
"DefaultConnection" : "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=TestDB;Integrated Security=True;"
}
}
▶ Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using TestProject.Data;
namespace TestProject
{
/// <summary>
/// 시작
/// </summary>
public class Startup
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 구성 - Configuration
/// <summary>
/// 구성
/// </summary>
public IConfiguration Configuration { get; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - Startup(configuration)
/// <summary>
/// 생성자
/// </summary>
/// <param name="configuration">구성</param>
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 서비스 컬렉션 구성하기 - ConfigureServices(services)
/// <summary>
/// 서비스 컬렉션 구성하기
/// </summary>
/// <param name="services">서비스 컬렉션</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DatabaseContext>
(
options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
}
);
services.AddRazorPages();
}
#endregion
#region 구성하기 - Configure(app, environment)
/// <summary>
/// 구성하기
/// </summary>
/// <param name="app">애플리케이션 빌더</param>
/// <param name="environment">웹 호스트 환경</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment)
{
if(environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
#endregion
}
}
▶ Pages/Movies/Index.cshtml
@page
@using TestProject.Models
@model TestProject.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.MovieList[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.MovieList[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.MovieList[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.MovieList[0].Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach(Movie movie in Model.MovieList)
{
<tr>
<td>
@Html.DisplayFor(modelItem => movie.Title)
</td>
<td>
@Html.DisplayFor(modelItem => movie.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => movie.Genre)
</td>
<td>
@Html.DisplayFor(modelItem => movie.Price)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@movie.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@movie.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@movie.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
▶ Pages/Movies/Index.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using TestProject.Data;
using TestProject.Models;
namespace TestProject.Pages.Movies
{
/// <summary>
/// 인덱스 모델
/// </summary>
public class IndexModel : PageModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 컨텍스트
/// </summary>
private readonly DatabaseContext context;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 영화 리스트 - MovieList
/// <summary>
/// 영화 리스트
/// </summary>
public IList<Movie> MovieList { get;set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - IndexModel(context)
/// <summary>
/// 생성자
/// </summary>
/// <param name="context">컨텍스트</param>
public IndexModel(DatabaseContext context)
{
this.context = context;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region GET 비동기 처리하기 - OnGetAsync()
/// <summary>
/// GET 비동기 처리하기
/// </summary>
/// <returns>태스크</returns>
public async Task OnGetAsync()
{
MovieList = await this.context.Movie.ToListAsync();
}
#endregion
}
}
▶ Pages/Movies/Create.cshtml
@page
@model TestProject.Pages.Movies.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Movie.Title" class="control-label"></label>
<input asp-for="Movie.Title" class="form-control" />
<span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.ReleaseDate" class="control-label"></label>
<input asp-for="Movie.ReleaseDate" class="form-control" />
<span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.Genre" class="control-label"></label>
<input asp-for="Movie.Genre" class="form-control" />
<span asp-validation-for="Movie.Genre" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.Price" class="control-label"></label>
<input asp-for="Movie.Price" class="form-control" />
<span asp-validation-for="Movie.Price" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
▶ Pages/Movies/Create.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Threading.Tasks;
using TestProject.Data;
using TestProject.Models;
namespace TestProject.Pages.Movies
{
/// <summary>
/// 생성 모델
/// </summary>
public class CreateModel : PageModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 컨텍스트
/// </summary>
private readonly DatabaseContext context;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 영화 - Movie
/// <summary>
/// 영화
/// </summary>
[BindProperty]
public Movie Movie { get; set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - CreateModel(context)
/// <summary>
/// 생성자
/// </summary>
/// <param name="context">컨텍스트</param>
public CreateModel(DatabaseContext context)
{
this.context = context;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region GET 처리하기 - OnGet()
/// <summary>
/// GET 처리하기
/// </summary>
/// <returns>액션 결과</returns>
public IActionResult OnGet()
{
return Page();
}
#endregion
#region POST 비동기 처리하기 - OnPostAsync()
/// <summary>
/// POST 비동기 처리하기
/// </summary>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> OnPostAsync()
{
if(!ModelState.IsValid)
{
return Page();
}
this.context.Movie.Add(Movie);
await this.context.SaveChangesAsync();
return RedirectToPage("./Index");
}
#endregion
}
}
▶ Pages/Movies/Edit.cshtml
@page
@model TestProject.Pages.Movies.EditModel
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Movie.ID" />
<div class="form-group">
<label asp-for="Movie.Title" class="control-label"></label>
<input asp-for="Movie.Title" class="form-control" />
<span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.ReleaseDate" class="control-label"></label>
<input asp-for="Movie.ReleaseDate" class="form-control" />
<span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.Genre" class="control-label"></label>
<input asp-for="Movie.Genre" class="form-control" />
<span asp-validation-for="Movie.Genre" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.Price" class="control-label"></label>
<input asp-for="Movie.Price" class="form-control" />
<span asp-validation-for="Movie.Price" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
▶ Pages/Movies/Edit.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading.Tasks;
using TestProject.Data;
using TestProject.Models;
namespace TestProject.Pages.Movies
{
/// <summary>
/// 편집 모델
/// </summary>
public class EditModel : PageModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 컨텍스트
/// </summary>
private readonly DatabaseContext context;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 영화 - Movie
/// <summary>
/// 영화
/// </summary>
[BindProperty]
public Movie Movie { get; set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - EditModel(context)
/// <summary>
/// 생성자
/// </summary>
/// <param name="context">컨텍스트</param>
public EditModel(DatabaseContext context)
{
this.context = context;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region GET 비동기 처리하기 - OnGetAsync(id)
/// <summary>
/// GET 비동기 처리하기
/// </summary>
/// <param name="id">ID</param>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> OnGetAsync(int? id)
{
if(id == null)
{
return NotFound();
}
Movie = await this.context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if(Movie == null)
{
return NotFound();
}
return Page();
}
#endregion
#region POST 비동기 처리하기 - OnPostAsync()
/// <summary>
/// POST 비동기 처리하기
/// </summary>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> OnPostAsync()
{
if(!ModelState.IsValid)
{
return Page();
}
this.context.Attach(Movie).State = EntityState.Modified;
try
{
await this.context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
if(!MovieExists(Movie.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 영화 존재 여부 구하기 - MovieExists(id)
/// <summary>
/// 영화 존재 여부 구하기
/// </summary>
/// <param name="id">ID</param>
/// <returns>영화 존재 여부</returns>
private bool MovieExists(int id)
{
return this.context.Movie.Any(e => e.ID == id);
}
#endregion
}
}
▶ Pages/Movies/Delete.cshtml
@page
@model TestProject.Pages.Movies.DeleteModel
@{
ViewData["Title"] = "Delete";
}
<h1>Delete</h1>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Movie</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.Title)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.Title)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.ReleaseDate)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.ReleaseDate)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.Genre)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.Genre)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.Price)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.Price)
</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="Movie.ID" />
<input type="submit" value="Delete" class="btn btn-danger" /> |
<a asp-page="./Index">Back to List</a>
</form>
</div>
▶ Pages/Movies/Delete.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using TestProject.Data;
using TestProject.Models;
namespace TestProject.Pages.Movies
{
/// <summary>
/// 삭제 모델
/// </summary>
public class DeleteModel : PageModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 컨텍스트
/// </summary>
private readonly DatabaseContext context;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 영화 - Movie
/// <summary>
/// 영화
/// </summary>
[BindProperty]
public Movie Movie { get; set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DeleteModel(context)
/// <summary>
/// 생성자
/// </summary>
/// <param name="context">컨텍스트</param>
public DeleteModel(DatabaseContext context)
{
this.context = context;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region GET 비동기 처리하기 - OnGetAsync(id)
/// <summary>
/// GET 비동기 처리하기
/// </summary>
/// <param name="id">ID</param>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> OnGetAsync(int? id)
{
if(id == null)
{
return NotFound();
}
Movie = await this.context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if(Movie == null)
{
return NotFound();
}
return Page();
}
#endregion
#region POST 비동기 처리하기 - OnPostAsync(id)
/// <summary>
/// POST 비동기 처리하기
/// </summary>
/// <param name="id">ID</param>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> OnPostAsync(int? id)
{
if(id == null)
{
return NotFound();
}
Movie = await this.context.Movie.FindAsync(id);
if(Movie != null)
{
this.context.Movie.Remove(Movie);
await this.context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
#endregion
}
}
▶ Pages/Movies/Details.cshtml
@page
@model TestProject.Pages.Movies.DetailsModel
@{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>Movie</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.Title)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.Title)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.ReleaseDate)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.ReleaseDate)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.Genre)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.Genre)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Movie.Price)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Movie.Price)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="@Model.Movie.ID">Edit</a> |
<a asp-page="./Index">Back to List</a>
</div>
▶ Pages/Movies/Details.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using TestProject.Data;
using TestProject.Models;
namespace TestProject.Pages.Movies
{
/// <summary>
/// 상세 모델
/// </summary>
public class DetailsModel : PageModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 컨텍스트
/// </summary>
private readonly DatabaseContext context;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 영화 - Movie
/// <summary>
/// 영화
/// </summary>
[BindProperty]
public Movie Movie { get; set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DetailsModel(context)
/// <summary>
/// 생성자
/// </summary>
/// <param name="context">컨텍스트</param>
public DetailsModel(DatabaseContext context)
{
this.context = context;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region GET 비동기 처리하기 - OnGetAsync(id)
/// <summary>
/// GET 비동기 처리하기
/// </summary>
/// <param name="id">ID</param>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> OnGetAsync(int? id)
{
if(id == null)
{
return NotFound();
}
Movie = await context.Movie.FirstOrDefaultAsync(m => m.ID == id);
if(Movie == null)
{
return NotFound();
}
return Page();
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > ASP.NET MVC' 카테고리의 다른 글
[C#/ASP.NET MVC/.NETCORE] @model 지시문 사용하기 (0) | 2020.10.18 |
---|---|
[C#/ASP.NET MVC/.NETCORE] @page 지시문 사용하기 (0) | 2020.10.18 |
[C#/ASP.NET MVC/.NETCORE] dotnet aspnet-codegenerator razorpage 명령 : 도움말 보기 (0) | 2020.10.18 |
[C#/ASP.NET MVC/.NETCORE] dotnet aspnet-codegenerator razorpage 명령 : 스캐폴딩 기능을 사용해 CRUD 페이지 추가하기 (0) | 2020.10.18 |
[C#/ASP.NET MVC/.NETCORE] Entity Framework Core를 사용해 SQL Server 접속하기 (0) | 2020.10.18 |
[C#/ASP.NET MVC/.NETCORE] 스캐폴딩에 필요한 패키지 (0) | 2020.10.17 |
[C#/ASP.NET MVC/.NETCORE] 누겟 설치 : Microsoft.VisualStudio.Web.CodeGeneration.Design (0) | 2020.10.17 |
[C#/ASP.NET MVC/.NETCORE] dotnet tool install 명령 : 스캐폴딩 도구 설치하기 (0) | 2020.10.17 |
[C#/ASP.NET MVC/.NETCORE] dotnet dev-certs https 명령 : 개발 인증서 신뢰하기 (0) | 2020.10.17 |
[C#/ASP.NET MVC/.NETCORE] dotnet new webapp 명령 : RAZOR 페이지 웹앱 만들기 (0) | 2020.10.17 |
댓글을 달아 주세요