제니노트

Edit [C#] 본문

C#/C#

Edit [C#]

yangjennie 2023. 9. 25. 11:46
반응형

ClubController.cs

using CoreProjectPrac.Data; //DB컨텍스트
using CoreProjectPrac.Interfaces;
using CoreProjectPrac.Models;
using CoreProjectPrac.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Diagnostics.Eventing.Reader;
using System.Reflection.Emit;

namespace CoreProjectPrac.Controllers
{
    public class ClubController : Controller //Controller 클래스 상속 
    {
        //주입 생성자 정의 
        private readonly IClubRepository _clubRepository;
        private IPhotoService _photoService; 

        public ClubController(IClubRepository clubRepository, IPhotoService photoService) //IClubRepository 인터페이스 주입
        {

            _clubRepository = clubRepository;
            _photoService = photoService;
        }


        public async Task<IActionResult> Index()  //사용자의 요청을 처리, 인덱스 뷰를 반환 C 

        {
            IEnumerable<Club> clubs = await _clubRepository.GetAll();  //M 모든 클럽 정보 반환 
            //clubs 테이블의 모든 레코드를 가져와서 저장 
            return View(clubs); //V  
        }


        public async Task<IActionResult> Detail(int id) //상세정보 
        {

            Club club = await _clubRepository.GetByIdAsync(id);  //클럽정보 id를 통해 가져오기 
            return View(club);
        }

        public IActionResult Create() //클럽 생성뷰
            //IActionResult : 액션 메서드가 다양한 결과를 반환할 수 있도록 하는 인터페이스 
        {
            return View(); //HTML 페이지 표시, ViewResult 반환 
        }

        [HttpPost]
        public async Task<IActionResult> Create(CreateClubViewModel clubVM) //클럽 생성에 필요한 정보 포함하여 제출
        {
            if (!ModelState.IsValid) //클럽 상태가 유효하지 않을 경우 
            {
                //이미지 업로드 시도
                //업로드 수행하고 업로드 결과를 result에 
                var result = await _photoService.AddPhotoAsync(clubVM.Image); 

                var club = new Club //CreateViewModel 에서 받아온 정보와 이미지 결과를 사용하여
                //클럽 객체 초기화 
                {
                    Title = clubVM.Title,
                    Description = clubVM.Description,
                    Image = result.Url.ToString(),
                    Address = new Address
                    {
                        Street = clubVM.Address.Street,
                        City = clubVM.Address.City,
                        State = clubVM.Address.State

                    }
                };
                _clubRepository.Add(club); //유효한 경우 클럽 정보를 DB에 추가한다. 
                return RedirectToAction("Index"); //저장이 끝나면 Index 메서드로 리다이렉션
            }
            else
            {
                //이미지 업로드에 실패한 경우 클라이언트에 표시 
                ModelState.AddModelError("", "Photo upload failed");
            }
            return View(clubVM); //원래의 Create 뷰로 

        }

        public async Task<IActionResult> Edit(int id) //클럽 정보 수정 
        {
            var club = await _clubRepository.GetByIdAsync(id);//클럽 정보 DB에서 가져오기 
            if (club == null) return View("Error"); //클럽 존재하지 않으면 Error 뷰 및 중단 
            var clubVM = new EditClubViewModel //수정 폼에 현재 정보 채우기 
            {
                Title = club.Title,
                Description = club.Description,
                AddressId = club.AddressId,
                Address = club.Address,
                URL = club.Image,
                ClubCategory = club.ClubCategory
            };
            return View(clubVM); 
        }

        [HttpPost]
        public async Task<IActionResult> Edit(int id, EditClubViewModel clubVM) //Post 액션 메서드 
        {
            if (!ModelState.IsValid) //유효성 검사 
            {
                ModelState.AddModelError("", "Faild to edit club"); //오류메시지를 모델 상태에 추가 
                return View("Edit", clubVM); //편집 폼 다시보여주기 
            }

            var userClub = await _clubRepository.GetByIdAsyncNoTracking(id); //클럽 정보 가져오기 
            //NoTracking : 이전 정보를 가져오는 단계에서 추적이 필요하지 않으므로 DB 추적을 하지 않도록 한다.

            if (userClub != null)
            {
                try
                {
                    await _photoService.DeletePhotoAsync(userClub.Image); //이미지삭제 
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "Could not delete Photo");
                    return View(clubVM);

                }
                var photoResult = await _photoService.AddPhotoAsync(clubVM.Image); //새 이미지 업로드
                var club = new Club //클럽객체 초기화 
                {
                    Id = id,
                    Title = clubVM.Title,
                    Description = clubVM.Description,
                    Image = photoResult.Url.ToString(),
                    AddressId = clubVM.AddressId,
                    Address = clubVM.Address,
                };

                _clubRepository.Update(club); // 데이터베이스에 클럽 정보 업데이트 

                return RedirectToAction("Index"); //Index로 리다이렉션 
            }
            else //실패시 
            {
                return View(clubVM); //원래의 편집뷰로 
             }

        }

    }
}

EditClubViewModel.cs

using CoreProjectPrac.Data.Enum;
using CoreProjectPrac.Models;

namespace CoreProjectPrac.ViewModels
{
    //뷰모델을 이용하여 클럽 정보를 편집하는 폼에 
    //필요한 데이터를 전달
    //사용자가 입력한 정보 받아서 처리
    public class EditClubViewModel
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public IFormFile Image { get; set; }
        public string? URL { get; set; }
        public int? AddressId { get; set; }
        public Address? Address { get; set; }
        public ClubCategory ClubCategory { get; set; }
    }
}
@using CoreProjectPrac.Data.Enum;
@using CoreProjectPrac.ViewModels
@model EditClubViewModel
<!-- EditClubViewModel을 기반으로 함. -->
@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<!-- 파일 업로드 지원하도록 폼을 설정,Edit으로 액션 메서드 -->
<form method="post" asp-action="Edit" enctype="multipart/form-data">
    <input type="hidden" value="AddressId" id="AddressId" />
    <div class="form-group">
        <!--EditClubViewModel 모델 속성과 입력 필드 연결-->
        <label asp-for="Title">Title</label>
        <input asp-for="Title" class="form-control" placeholder="Title">
        <span asp-validation-for="Title" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Description">Description</label>
        <input asp-for="Description" class="form-control" placeholder="Description">
        <span asp-validation-for="Description" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="ClubCategory">Club Category</label>
        <!-- 드롭다운 목록과 모델 속성을 연결-->
        <!--열거형을 목록으로 변환-->
        <select asp-for="ClubCategory" asp-items="@Html.GetEnumSelectList<ClubCategory>()" class="form-control">
            <option selected="selected" value="">--Select--</option>
        </select>
        <span asp-validation-for="ClubCategory" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Address.Street">Street</label>
        <input asp-for="Address.Street" class="form-control" placeholder="Street">
        <span asp-validation-for="Address.Street" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Address.City">City</label>
        <input asp-for="Address.City" class="form-control" placeholder="City">
        <span asp-validation-for="Address.Street" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Address.State">State</label>
        <input asp-for="Address.State" class="form-control" placeholder="Street">
        <span asp-validation-for="Address.State" class="text-danger"></span>
    </div>
    <div class="form-group">
        <!-- 파일 업로드 필드 -->
        <label asp-for="Image">Image</label>
        <input asp-for="Image" type="file" class="form-control" placeholder="Image">
        <span asp-validation-for="Image" class="text-danger"></span>

    </div>
    <!--제출 , 폼 데이터가 서버로 전송되어 처리 -->
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

 

ClubRepository.cs

using CoreProjectPrac.Data;
using CoreProjectPrac.Interfaces;
using CoreProjectPrac.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace CoreProjectPrac.Repository
{
    public class ClubRepository : IClubRepository //IClubRepository 인터페이스 구현
    {
        private readonly ApplicationDbContext _context; //Dbcontext 

        public ClubRepository(ApplicationDbContext context)
        {
            _context = context;   
        }
        public bool Add(Club club)
        {
            _context.Add(club);  //DBcontext에 클럽 추가 
            return Save();
        }

        public bool Delete(Club club)
        {
            _context.Remove(club); //Dbcontext에서 클럽 정보 제거
            return Save(); //DB 저장 후 결과 반환 
        }

        // _context.Clubs를 통해 Clubs 테이블에 엑세스 
        // ToListasync()로 모든 클럽 정보를 조회
        // Entity Framework core는 DB 쿼리를 생성하고 실행 
        // await 를 통해 비동기 작업이 완료될 때 까지 메서드의 실행을 일시 중지
        // DB에서 모든 클럽 정보가 가져오면 ToListAsync()가 IEnumerable<Club>형식으로 반환
        public async Task<IEnumerable<Club>> GetAll() //모든 클럽 정보 가져오기 
        {
           return await  _context.Clubs.ToListAsync(); 
            
        }
        // _context.Clubs를 통해 Clubs 테이블에 엑세스 
        //.Include(i=>i.Address) 를 사용하여 클럽 엔터티의 Address 속성을 함께 로드
        //클럽 엔티티 조회 동시에 연결된 주소 속성도 함께 조회 
        //.FirstOrDefaultAsync(i=>i.Id==id)
        // 주어진 ID와 일치하는 첫 번째 클럽을 비동기적으로 조회
        // await 로 메서드의 실행을 일시 중지
        // ID에 해당하는 클럽이 DB에서 찾아지면 해당 클럽 정보를 객체로 반환
        // 찾지 못하면 null 
        // 지연로딩 방지! 
        public async Task<Club> GetByIdAsync(int id) //ID 기반으로 클럽 정보 가져오기 
        {
            //Include로 클럽에 주소 정보도 함께 조회 
            return await _context.Clubs.Include(i => i.Address).FirstOrDefaultAsync(i => i.Id == id);

        }

        public async Task<Club> GetByIdAsyncNoTracking(int id) //조회된 엔터티에 대한 추적을 비활성화 
        {
            //새로운 정보를 입력받아 업데이트 하는 경우 유용함.
            return await _context.Clubs.Include(i => i.Address).AsNoTracking().FirstOrDefaultAsync(i => i.Id == id);
        }

        public async Task<IEnumerable<Club>> GetClubByCity(string city) //도시 이름 기반으로 클럽 정보 가져오기 
        {
            
            return await _context.Clubs.Where(c => c.Address.City.Contains(city)).ToListAsync();
        }

        public bool Save()
        {
            var saved = _context.SaveChanges(); //변경사항을 DB에 저장 
            return saved > 0 ? true : false; 
        }

        public bool Update(Club club) //클럽 정보 업데이트 
        {
            _context.Update(club); 
            return Save();
        }

     
    }
}

 

IClubRepository.cs

using CoreProjectPrac.Models;

namespace CoreProjectPrac.Interfaces
{
    public interface IClubRepository
    {
        Task<IEnumerable<Club>> GetAll(); //모든 클럽 리스트 반환 
        Task<Club> GetByIdAsync(int id); //Id를 기반으로 클럽 객체를 비동기적으로 가져옴

        Task<Club> GetByIdAsyncNoTracking(int id); //Id를 기반으로 클럽 객체를 비동기적으로 가져옴

        // 도시 이름 기반으로 클럽 리스트를 비동기적으로 가져옴
        Task<IEnumerable<Club>> GetClubByCity(string city);

        bool Add(Club club); //새로운 클럽 추가 
        bool Update(Club club); //클럽 정보 업데이트
        bool Delete(Club club); //클럽 삭제 
        bool Save(); //변경사항 저장 



    }
}

RaceRepository.cs 

 public async Task<Race> GetByIdAsyncNoTracking(int id)
 {
     return await _context.Races.Include(i => i.Address).AsNoTracking().FirstOrDefaultAsync(); //모든 레코드를 다 가져온다.
 }
반응형

'C# > C#' 카테고리의 다른 글

변수와 데이터 형식 변환(Type Conversion) [C#]  (1) 2023.10.10
Delete [C#]  (0) 2023.09.25
CREATE [C#]  (0) 2023.09.25
DI, Repository Pattern [C#]  (0) 2023.09.25
Detail View 만들기 [C#]  (0) 2023.09.25
Comments