개발자 가이드: UserRoleManagement 시스템

  • 6 minutes to read

목차

  1. 개요
  2. 시스템 요구사항
  3. 구조 및 디자인
  4. 모델
  5. 컨트롤러: UserRoleManagementController
  6. 라우팅 및 URL 구조
  7. 에러 핸들링
  8. 보안 고려사항
  9. 추가 개발 노트

개요

이 문서는 UserRoleManagement 시스템의 개발을 위한 기술 가이드를 제공합니다. 이 시스템은 사용자의 역할을 관리하는 기능을 제공하며, ASP.NET Core MVC 프레임워크를 사용하여 구현됩니다.

시스템 요구사항

  • .NET Core 6.0 이상(학습은 8.0 이상 버전 권장)
  • ASP.NET Core MVC
  • Entity Framework Core
  • Microsoft SQL Server (또는 호환 가능한 데이터베이스)

구조 및 디자인

시스템은 MVC 패턴을 따르며, 주요 구성 요소는 다음과 같습니다:

  • 모델: 데이터 구조와 비즈니스 로직을 정의합니다.
  • : 사용자 인터페이스를 구현합니다.
  • 컨트롤러: 사용자 요청을 처리하고 응답을 반환합니다.

모델

  • UserRoleListViewModel: 사용자와 그들의 역할을 나타냅니다.
  • UserRoleEditViewModel: 사용자 역할 편집에 사용됩니다.

컨트롤러: UserRoleManagementController

UserRoleManagementController는 사용자 역할을 관리하는 핵심 컨트롤러입니다.

주요 기능

  • Index: 모든 사용자와 그들의 역할을 나열합니다.
  • Manage: 특정 사용자의 역할을 관리합니다.

액션 메서드

  • Index(): 사용자 역할 목록을 표시합니다.
  • Manage(string userId): 특정 사용자의 역할을 관리하는 페이지를 제공합니다.
  • Manage(List<UserRoleEditViewModel> model, string userId): 사용자의 역할 변경 사항을 저장합니다.

  • UserRoleList.cshtml: 사용자 역할 목록을 보여줍니다.
  • UserRoleEdit.cshtml: 특정 사용자의 역할을 관리하는 인터페이스를 제공합니다.

라우팅 및 URL 구조

  • Index: /Administrations/UserRoleManagement
  • Manage: /Administrations/UserRoleManagement/Manage/{userId}

에러 핸들링

  • 사용자가 존재하지 않는 경우, NotFound 뷰를 반환합니다.
  • 역할 변경 과정에서 오류가 발생하면, 사용자에게 오류 메시지를 표시합니다.

보안 고려사항

  • UserRoleManagementController는 "Administrators" 역할을 가진 사용자만 접근할 수 있습니다.
  • 사용자의 입력 데이터는 서버 측에서 유효성 검사를 거칩니다.

추가 개발 노트

  • 이 시스템은 확장성을 고려하여 설계되었습니다. 필요에 따라 추가적인 기능이나 변경 사항을 쉽게 적용할 수 있습니다.
  • 사용자 인터페이스는 향후 사용성 개선을 위해 지속적으로 업데이트 될 수 있습니다.

이 가이드는 개발자가 UserRoleManagement 시스템을 이해하고 효율적으로 작업을 수행할 수 있도록 도와줄 것입니다. 개발 과정에서 발생하는 문제나 질문 사항은 개발 팀 또는 프로젝트 관리자에게 문의하세요.

전체 소스

VisualAcademy\Models\Administrations\UserRoleListViewModel.cs

using System.Collections.Generic;

namespace VisualAcademy.Models.Administrations.UserRoleManagement
{
    public class UserRoleListViewModel
    {
        public string UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }
        public IEnumerable<string> Roles { get; set; }
    }
}

VisualAcademy\Models\Administrations\UserRoleEditViewModel.cs

namespace VisualAcademy.Models.Administrations.UserRoleManagement
{
    public class UserRoleEditViewModel
    {
        public string RoleId { get; set; }
        public string RoleName { get; set; }
        public bool Selected { get; set; }
    }
}

VisualAcademy\Controllers\Administrations\UserRoleManagementController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VisualAcademy.Models;
using VisualAcademy.Models.Administrations;

namespace VisualAcademy.Controllers.Administrations.UserRoleManagement
{
    [Authorize(Roles = "Administrators")]
    [Route("Administrations/UserRoleManagement")]
    public class UserRoleManagementController : Controller
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly RoleManager<ApplicationRole> _roleManager;

        public UserRoleManagementController(UserManager<ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager)
        {
            _userManager = userManager;
            _roleManager = roleManager;
        }

        [HttpGet("")]
        public async Task<IActionResult> Index()
        {
            var users = await _userManager.Users.ToListAsync();
            var userRolesViewModel = new List<UserRoleListViewModel>();
            foreach (var user in users)
            {
                var thisViewModel = new UserRoleListViewModel
                {
                    UserId = user.Id,
                    Email = user.Email,
                    FirstName = user.FirstName,
                    LastName = user.LastName,
                    Roles = await GetUserRoles(user)
                };
                userRolesViewModel.Add(thisViewModel);
            }
            return View("~/Views/Administrations/UserRoleManagement/UserRoleList.cshtml", userRolesViewModel);
        }

        [HttpGet("Manage/{userId}")]
        public async Task<IActionResult> Manage(string userId)
        {
            ViewBag.userId = userId;
            var user = await _userManager.FindByIdAsync(userId);
            if (user == null)
            {
                ViewBag.ErrorMessage = $"User with Id = {userId} cannot be found";
                return View("NotFound");
            }
            ViewBag.UserName = user.UserName;
            var model = new List<UserRoleEditViewModel>();
            foreach (var role in _roleManager.Roles)
            {
                var userRolesViewModel = new UserRoleEditViewModel
                {
                    RoleId = role.Id,
                    RoleName = role.Name,
                    Selected = await _userManager.IsInRoleAsync(user, role.Name)
                };
                model.Add(userRolesViewModel);
            }
            return View("~/Views/Administrations/UserRoleManagement/UserRoleEdit.cshtml", model);
        }

        [HttpPost("Manage/{userId}")]
        public async Task<IActionResult> Manage(List<UserRoleEditViewModel> model, string userId)
        {
            var user = await _userManager.FindByIdAsync(userId);
            if (user == null)
            {
                return View("NotFound");
            }

            var roles = await _userManager.GetRolesAsync(user);
            var result = await _userManager.RemoveFromRolesAsync(user, roles);
            if (!result.Succeeded)
            {
                ModelState.AddModelError("", "Cannot remove user existing roles");
                return View("UserRoleEdit", model);
            }

            result = await _userManager.AddToRolesAsync(user, model.Where(x => x.Selected).Select(y => y.RoleName));
            if (!result.Succeeded)
            {
                ModelState.AddModelError("", "Cannot add selected roles to user");
                return View("UserRoleEdit", model);
            }
            return RedirectToAction("Index");
        }

        private async Task<IEnumerable<string>> GetUserRoles(ApplicationUser user)
        {
            return new List<string>(await _userManager.GetRolesAsync(user));
        }
    }
}

VisualAcademy\Views\Administrations\UserRoleManagement\UserRoleList.cshtml

@using VisualAcademy.Models.Administrations.UserRoleManagement
@model List<UserRoleListViewModel>
@{
    ViewData["Title"] = "User Roles";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h3>User Roles</h3>
<table class="table table-striped">
    <thead>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Roles</th>
            <th>Action</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var user in Model)
        {
            <tr>
                <td>@user.FirstName</td>
                <td>@user.LastName</td>
                <td>@user.Email</td>
                <td>@string.Join(", ", user.Roles)</td>
                <td>
                    <a class="btn btn-primary" 
                        asp-controller="UserRoleManagement" 
                        asp-action="Manage" 
                        asp-route-userId="@user.UserId">Manage Roles</a>
                </td>
            </tr>
        }
    </tbody>
</table>

<a href="/Administrations/Users" class="btn btn-success">New User</a>

VisualAcademy\Views\Administrations\UserRoleManagement\UserRoleEdit.cshtml

@using VisualAcademy.Models.Administrations.UserRoleManagement
@model List<UserRoleEditViewModel>
@{
    ViewData["Title"] = "Manage User Roles";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<form method="post" asp-action="Manage" asp-controller="UserRoleManagement" asp-route-userId="@ViewBag.userId">
    <div class="card">
        <div class="card-header">
            <h2>Manage User Roles for @ViewBag.UserName</h2>
        </div>
        <div class="card-body">
            @for (int i = 0; i < Model.Count; i++)
            {
                <div class="form-check m-1">
                    <input type="hidden" asp-for="@Model[i].RoleId" />
                    <input type="hidden" asp-for="@Model[i].RoleName" />
                    <input asp-for="@Model[i].Selected" class="form-check-input" />
                    <label class="form-check-label" asp-for="@Model[i].Selected">@Model[i].RoleName</label>
                </div>
            }
            <div asp-validation-summary="All" class="text-danger"></div>
        </div>
        <div class="card-footer">
            <input type="submit" value="Update" class="btn btn-primary" style="width:auto" />
            <a asp-action="Index" class="btn btn-primary" style="width:auto">Cancel</a>
        </div>
    </div>
</form>

<p class="text-danger small">
    <em>Applying roles requires logging out and logging in again.</em>
</p>
VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com