■ List 클래스에서 무작위로 항목을 섞는 방법을 보여준다. ▶ List 클래스 : 무작위로 항목 섞기 예제 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
using System; using System.Collections.Generic; Random random = new Random(DateTime.Now.Millisecond); List<string> list = new List<string>() { "가", "나", "다", "라", "마" }; Shuffle<string>(random, list); foreach(string item in list) { Console.WriteLine(item); } |
▶ List 클래스 :
더 읽기
■ 모델 빌더를 사용해 택시 요금을 예측하는 방법을 보여준다. [TestLibrary 프로젝트] ▶ ModelInput.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
using Microsoft.ML.Data; namespace TestLibrary { /// <summary> /// 모델 입력 /// </summary> public class ModelInput { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 공급자 ID - VendorID /// <summary> /// 공급자 ID /// </summary> [ColumnName("vendor_id"), LoadColumn(0)] public string VendorID { get; set; } #endregion #region 요금 코드 - RateCode /// <summary> /// 요금 코드 /// </summary> [ColumnName("rate_code"), LoadColumn(1)] public float RateCode { get; set; } #endregion #region 승객 수 - PassengerCount /// <summary> /// 승객 수 /// </summary> [ColumnName("passenger_count"), LoadColumn(2)] public float PassengerCount { get; set; } #endregion #region 이동 시간 (단위 : 초) - TripTimeInSeconds /// <summary> /// 이동 시간 (단위 : 초) /// </summary> [ColumnName("trip_time_in_secs"), LoadColumn(3)] public float TripTimeInSeconds { get; set; } #endregion #region 이동 거리 - TripDistance /// <summary> /// 이동 거리 /// </summary> [ColumnName("trip_distance"), LoadColumn(4)] public float TripDistance { get; set; } #endregion #region 지불 타입 - PaymentType /// <summary> /// 지불 타입 /// </summary> [ColumnName("payment_type"), LoadColumn(5)] public string PaymentType { get; set; } #endregion #region 요금 - FareAmount /// <summary> /// 요금 /// </summary> [ColumnName("fare_amount"), LoadColumn(6)] public float FareAmount { get; set; } #endregion } } |
▶ ModelOutput.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
namespace TestLibrary { /// <summary> /// 모델 입력 /// </summary> public class ModelOutput { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 점수 - Score /// <summary> /// 점수 /// </summary> public float Score { get; set; } #endregion } } |
▶ ConsumeModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
using Microsoft.ML; using System; namespace TestLibrary { /// <summary> /// 모델 소비 /// </summary> public class ConsumeModel { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 예측 엔진 LAZY /// </summary> private static Lazy<PredictionEngine<ModelInput, ModelOutput>> _predictionEngineLazy = new Lazy<PredictionEngine<ModelInput, ModelOutput>>(CreatePredictionEngine); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 예측 엔진 생성하기 - CreatePredictionEngine() /// <summary> /// 예측 엔진 생성하기 /// </summary> /// <returns>예측 엔진</returns> public static PredictionEngine<ModelInput, ModelOutput> CreatePredictionEngine() { MLContext context = new MLContext(); string filePath = @"WEIGHT\MLModel.zip"; ITransformer mlModel = context.Model.Load(filePath, out var modelInputSchema); PredictionEngine<ModelInput, ModelOutput> predictionEngine = context.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel); return predictionEngine; } #endregion #region 예측하기 - Predict(input) /// <summary> /// 예측하기 /// </summary> /// <param name="input">모델 입력</param> /// <returns>모델 출력</returns> public static ModelOutput Predict(ModelInput input) { ModelOutput result = _predictionEngineLazy.Value.Predict(input); return result; } #endregion } } |
[TestProtect 프로젝트]
더 읽기
■ Microsoft.Windows.SDK.Contracts 누겟을 설치하는 방법을 보여준다. 1. Visual Studio를 실행한다. 2. [도구] / [NuGet 패키지 관리자] / [패키지 관리자 콘솔] 메뉴를 실행한다.
더 읽기
■ FaceDetector 클래스의 DetectFacesAsync 메소드를 사용해 얼굴을 탐지하는 방법을 보여준다. ▶ IFaceDetectionService.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
using System.Collections.Generic; using System.Drawing; using System.IO; using System.Threading.Tasks; using Windows.Media.FaceAnalysis; namespace TestProject { /// <summary> /// 얼굴 탐지 서비스 /// </summary> public interface IFaceDetectionService { //////////////////////////////////////////////////////////////////////////////////////////////////// Method #region 탐지 얼굴 리스트 구하기 - GetDetectedFaceList(stream) /// <summary> /// 탐지 얼굴 리스트 구하기 /// </summary> /// <param name="stream">스트림</param> /// <returns>탐지 얼굴 리스트 태스크</returns> Task<IList<DetectedFace>> GetDetectedFaceList(Stream stream); #endregion #region 탐지 얼굴 비트맵 구하기 - GetDetectedFaceBitmap(stream, detectedFaceList, boxColor, strokeThickness) /// <summary> /// 탐지 얼굴 비트맵 구하기 /// </summary> /// <param name="stream">스트림</param> /// <param name="detectedFaceList">탐지 얼굴 리스트</param> /// <param name="boxColor">박스 색상</param> /// <param name="strokeThickness">스트로크 두께</param> /// <returns>탐지 얼굴 비트맵</returns> Bitmap GetDetectedFaceBitmap(Stream stream, IList<DetectedFace> detectedFaceList, Color boxColor, int strokeThickness = 2); #endregion } } |
▶ FaceDetectionService.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Windows.Graphics.Imaging; using Windows.Media.FaceAnalysis; using Windows.Storage.Streams; namespace TestProject { /// <summary> /// 얼굴 탐지 서비스 /// </summary> public class FaceDetectionService : IFaceDetectionService { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 탐지 얼굴 리스트 구하기 - GetDetectedFaceList(stream) /// <summary> /// 탐지 얼굴 리스트 구하기 /// </summary> /// <param name="stream">스트림</param> /// <returns>탐지 얼굴 리스트 태스크</returns> public async Task<IList<DetectedFace>> GetDetectedFaceList(Stream stream) { IRandomAccessStream randomAccessStream = stream.AsRandomAccessStream(); var bitmapDecoder = await BitmapDecoder.CreateAsync(randomAccessStream); using SoftwareBitmap sourceBitmap = await bitmapDecoder.GetSoftwareBitmapAsync(); SoftwareBitmap targetBitmap = FaceDetector.IsBitmapPixelFormatSupported(sourceBitmap.BitmapPixelFormat) ? sourceBitmap : SoftwareBitmap.Convert(sourceBitmap, BitmapPixelFormat.Gray8); FaceDetector faceDetector = await FaceDetector.CreateAsync(); IList<DetectedFace> detectedFaceList = await faceDetector.DetectFacesAsync(targetBitmap); return detectedFaceList; } #endregion #region 탐지 얼굴 비트맵 구하기 - GetDetectedFaceBitmap(stream, detectedFaceList, boxColor, strokeThickness) /// <summary> /// 탐지 얼굴 비트맵 구하기 /// </summary> /// <param name="stream"></param> /// <param name="detectedFaceList"></param> /// <param name="boxColor"></param> /// <param name="strokeThickness"></param> /// <returns></returns> public System.Drawing.Bitmap GetDetectedFaceBitmap ( Stream stream, IList<DetectedFace> detectedFaceList, System.Drawing.Color boxColor, int strokeThickness = 2 ) { System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(stream); using(System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap)) { using System.Drawing.Pen pen = new System.Drawing.Pen(boxColor, strokeThickness); foreach(DetectedFace detectedFace in detectedFaceList) { BitmapBounds bitmapBounds = detectedFace.FaceBox; graphics.DrawRectangle ( pen, (int)bitmapBounds.X, (int)bitmapBounds.Y, (int)bitmapBounds.Width, (int)bitmapBounds.Height ); } } return bitmap; } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="800" Height="600" Title="FaceDetector 클래스 : DetectFacesAsync 메소드를 사용해 얼굴 탐지하기" FontFamily="나눔고딕코딩" FontSize="16"> <Grid> <Border Margin="10" BorderThickness="1" BorderBrush="Black"> <Image Name="image" /> </Border> </Grid> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
using System.IO; using System.Windows; using System.Windows.Media.Imaging; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); Loaded += Window_Loaded; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e) /// <summary> /// 윈도우 로드시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private async void Window_Loaded(object sender, RoutedEventArgs e) { FaceDetectionService service = new FaceDetectionService(); await using FileStream fileStream = File.OpenRead(@"IMAGE\sample.jpg"); var faces = await service.GetDetectedFaceList(fileStream); System.Drawing.Bitmap FacesBitmap = service.GetDetectedFaceBitmap(fileStream, faces, System.Drawing.Color.Red, 8); this.image.Source = GetBitmapImage(FacesBitmap); } #endregion //////////////////////////////////////////////////////////////////////////////// Function #region 비트맵 이미지 구하기 - GetBitmapImage(bitmap) /// <summary> /// 비트맵 이미지 구하기 /// </summary> /// <param name="bitmap">비트맵</param> /// <returns>비트맵 이미지</returns> private BitmapImage GetBitmapImage(System.Drawing.Bitmap bitmap) { using MemoryStream stream = new MemoryStream(); bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); stream.Position = 0; BitmapImage bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); bitmapImage.Freeze(); return bitmapImage; } #endregion } } |
더 읽기
■ BitmapImage 클래스를 사용해 WINFORM Bitmap 객체에서 비트맵 이미지를 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
using System.IO; using System.Windows.Media.Imaging; #region 비트맵 이미지 구하기 - GetBitmapImage(bitmap) /// <summary> /// 비트맵 이미지 구하기 /// </summary> /// <param name="bitmap">비트맵</param> /// <returns>비트맵 이미지</returns> public BitmapImage GetBitmapImage(System.Drawing.Bitmap bitmap) { using MemoryStream stream = new MemoryStream(); bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); stream.Position = 0; BitmapImage bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); bitmapImage.Freeze(); return bitmapImage; } #endregion |
■ IValueConverter 인터페이스를 구현해 비트맵→비트맵 소스 변환자를 사용하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
using System; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Windows.Data; using System.Windows.Media.Imaging; /// <summary> /// 비트맵→비트맵 소스 변환자 /// </summary> public class BitmapToBitmapSourceConverter : IValueConverter { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 변환하기 - Convert(sourceValue, targetType, parameter, cultureInfo) /// <summary> /// 변환하기 /// </summary> /// <param name="sourceValue">소스 값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">매개 변수</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>변환 값</returns> public object Convert(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo) { if(sourceValue is null) { return null; } using Bitmap bitmap = sourceValue as Bitmap; using MemoryStream stream = new MemoryStream(); bitmap.Save(stream, ImageFormat.Bmp); stream.Position = 0; BitmapImage bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); bitmapImage.Freeze(); return bitmapImage; } #endregion #region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, cultureInfo) /// <summary> /// 역변환하기 /// </summary> /// <param name="sourceValue">소스 값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">매개 변수</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>역변환 값</returns> public object ConvertBack(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo) { return Binding.DoNothing; } #endregion } |
■ ActionFilterAttribute 클래스를 사용해 액션 필터를 만드는 방법을 보여준다. ▶ SessionCheckActionFilterAttribute.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Routing; namespace TestProject { /// <summary> /// 세션 체크 액션 필터 어트리뷰트 /// </summary> public class SessionCheckActionFilterAttribute : ActionFilterAttribute { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 액션 실행시 처리하기 - OnActionExecuting(context) /// <summary> /// 액션 실행시 처리하기 /// </summary> /// <param name="context">컨텍스트</param> public override void OnActionExecuting(ActionExecutingContext context) { if(context.HttpContext.Session.GetString("Name") == null) { context.Result = new RedirectToRouteResult ( new RouteValueDictionary ( new { action = "Index", controller = "Home" } ) ); } base.OnActionExecuting(context); } #endregion } } |
▶ Controllers/HomeController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace TestProject.Controllers { /// <summary> /// 홈 컨트롤러 /// </summary> public class HomeController : Controller { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 인덱스 페이지 처리하기 - Index() /// <summary> /// 인덱스 페이지 처리하기 /// </summary> /// <returns>액션 결과</returns> public IActionResult Index() { HttpContext.Session.SetString("Name", "James"); return View(); } #endregion #region 개인 페이지 처리하기 - Private() /// <summary> /// 개인 페이지 처리하기 /// </summary> /// <returns>액션 결과</returns> [SessionCheckActionFilter] public IActionResult Private() { return View(); } #endregion } } |
▶ Views/Home/Index.cshtml
▶ Views/Home/Private.cshtml
|
@using Microsoft.AspNetCore.Http <p>개인 페이지</p> <hr /> <p>@Context.Session.GetString("Name")</p> |
▶
더 읽기
■ ResponseCompressionBuilderExtensions 클래스의 UseResponseCompression 확장 메소드를 사용해 응답 압축을 사용하는 방법을 보여준다. ▶ wwwroot/help.html
|
<html> <head> <title>도움말</title> </head> <body> <h1>도움말 페이지</h1> <hr /> </body> </html> |
▶ Controllers/HomeController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
using Microsoft.AspNetCore.Mvc; namespace TestProject.Controllers { /// <summary> /// 홈 컨트롤러 /// </summary> public class HomeController : Controller { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 인덱스 페이지 처리하기 - Index() /// <summary> /// 인덱스 페이지 처리하기 /// </summary> /// <returns>액션 결과</returns> public IActionResult Index() { return View(); } #endregion } } |
▶ Views/Home/Index.cshtml
▶
더 읽기
■ Microsoft.AspNetCore.ResponseCompression 누겟을 설치하는 방법을 보여준다. 1. Visual Studio를 실행한다. 2. [도구] / [NuGet 패키지 관리자] / [패키지 관리자 콘솔] 메뉴를 실행한다.
더 읽기
■ RazorPage 클래스의 Context 속성을 사용해 세션 데이터를 구하는 방법을 보여준다. ▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System; 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.AddSession ( options => { options.IdleTimeout = TimeSpan.FromSeconds(30); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; } ); services.AddControllersWithViews(); } #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("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseSession(); app.UseEndpoints ( endpoints => { endpoints.MapControllerRoute ( name : "default", pattern : "{controller=Home}/{action=Index}/{id?}" ); } ); } #endregion } } |
▶ Controllers/HomeController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace TestProject.Controllers { /// <summary> /// 홈 컨트롤러 /// </summary> public class HomeController : Controller { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 인덱스 페이지 처리하기 - Index() /// <summary> /// 인덱스 페이지 처리하기 /// </summary> /// <returns>액션 결과</returns> public IActionResult Index() { HttpContext.Session.SetString("Name", "James"); return View(); } #endregion #region 개인 페이지 처리하기 - Private() /// <summary> /// 개인 페이지 처리하기 /// </summary> /// <returns></returns> public IActionResult Private() { return View(); } #endregion } } |
▶ Views/Home/Index.cshtml
▶ Views/Home/Private.cshtml
더 읽기
■ SessionExtensions 클래스의 SetString/GetString 확장 메소드를 사용해 세션 데이터를 설정하고 구하는 방법을 보여준다. ▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System; 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.AddSession ( options => { options.IdleTimeout = TimeSpan.FromSeconds(30); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; } ); services.AddControllersWithViews(); } #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("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseSession(); app.UseEndpoints ( endpoints => { endpoints.MapControllerRoute ( name : "default", pattern : "{controller=Home}/{action=Index}/{id?}" ); } ); } #endregion } } |
▶ Controllers/HomeController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace TestProject.Controllers { /// <summary> /// 홈 컨트롤러 /// </summary> public class HomeController : Controller { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 인덱스 페이지 처리하기 - Index() /// <summary> /// 인덱스 페이지 처리하기 /// </summary> /// <returns>액션 결과</returns> public IActionResult Index() { HttpContext.Session.SetString("Name", "James"); return View(); } #endregion #region 개인 페이지 처리하기 - Private() /// <summary> /// 개인 페이지 처리하기 /// </summary> /// <returns></returns> public IActionResult Private() { string name = HttpContext.Session.GetString("Name"); ViewData["Name"] = name; return View(); } #endregion } } |
▶ Views/Home/Index.cshtml
더 읽기
■ HostingAbstractionsWebHostBuilderExtensions 클래스의 UseWebRoot 확장 메소드를 사용해 웹 루트 경로를 설정하는 방법을 보여준다. ▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; namespace TestProject { /// <summary> /// 프로그램 /// </summary> public class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 프로그램 시작하기 - Main(argumentArray) /// <summary> /// 프로그램 시작하기 /// </summary> /// <param name="argumentArray">인자 배열</param> public static void Main(string[] argumentArray) { CreateHostBuilder(argumentArray).Build().Run(); } #endregion #region 호스트 빌더 생성하기 - CreateHostBuilder(argumentArray) /// <summary> /// 호스트 빌더 생성하기 /// </summary> /// <param name="argumentArray">인자 배열</param> /// <returns>호스트 빌더</returns> public static IHostBuilder CreateHostBuilder(string[] argumentArray) => Host.CreateDefaultBuilder(argumentArray) .ConfigureWebHostDefaults ( builder => { builder.UseWebRoot("Content"); builder.UseStartup<Startup>(); } ); #endregion } } |
※ wwwroot 폴더를 Content 폴더로 변경하였다.
더 읽기
■ UseMiddlewareExtensions 클래스의 UseMiddleware 확장 메소드를 사용해 응답 가공 미들웨어를 등록하는 방법을 보여준다. ▶ ResponseProcessingMiddleware.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
using Microsoft.AspNetCore.Http; using System.Threading.Tasks; namespace TestProject { /// <summary> /// 응답 가공 미들웨어 /// </summary> public class ResponseProcessingMiddleware { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 다음 미들웨어 /// </summary> private RequestDelegate next; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - ResponseProcessingMiddleware(next) /// <summary> /// 생성자 /// </summary> /// <param name="next">다음 미들웨어</param> public ResponseProcessingMiddleware(RequestDelegate next) { this.next = next; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 호출하기 - Invoke(context) /// <summary> /// 호출하기 /// </summary> /// <param name="context">HTTP 컨텍스트</param> /// <returns>태스크</returns> public async Task Invoke(HttpContext context) { await next.Invoke(context); if(context.Response.StatusCode == 404) { await context.Response.WriteAsync ( $"<h1>You are not authorized to access to {context.Request.Host.Host}{context.Request.Path}</h1>" ); } } #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; 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.AddControllersWithViews(); } #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("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseMiddleware<ResponseProcessingMiddleware>(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints ( endpoints => { endpoints.MapControllerRoute ( name : "default", pattern : "{controller=Home}/{action=Index}/{id?}" ); } ); } #endregion } } |
TestProject.zip
■ UseMiddlewareExtensions 클래스의 UseMiddleware 확장 메소드를 사용해 종단 미들웨어를 등록하는 방법을 보여준다. ▶ TerminalMiddleware.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
using Microsoft.AspNetCore.Http; using System.Threading.Tasks; namespace TestProject { /// <summary> /// 종단 미들웨어 /// </summary> public class TerminalMiddleware { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 다음 미들웨어 /// </summary> private RequestDelegate next; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - TerminalMiddleware(next) /// <summary> /// 생성자 /// </summary> /// <param name="next">다음 미들웨어</param> public TerminalMiddleware(RequestDelegate next) { this.next = next; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 호출하기 - Invoke(context) /// <summary> /// 호출하기 /// </summary> /// <param name="context">HTTP 컨텍스트</param> /// <returns>태스크</returns> public async Task Invoke(HttpContext context) { Endpoint endpoint = context.GetEndpoint(); if(endpoint == null) { context.Response.StatusCode = StatusCodes.Status401Unauthorized; } else { await next.Invoke(context); } } #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; 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.AddControllersWithViews(); } #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("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseMiddleware<TerminalMiddleware>(); app.UseAuthorization(); app.UseEndpoints ( endpoints => { endpoints.MapControllerRoute ( name : "default", pattern : "{controller=Home}/{action=Index}/{id?}" ); } ); } #endregion } } |
TestProject.zip
■ UseMiddlewareExtensions 클래스의 UseMiddleware 확장 메소드를 사용해 요청 가공 미들웨어를 등록하는 방법을 보여준다. ▶ RequestProcessingMiddleware.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
using Microsoft.AspNetCore.Http; using System.Threading.Tasks; namespace TestProject { /// <summary> /// 요청 가공 미들웨어 /// </summary> public class RequestProcessingMiddleware { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 다음 미들웨어 /// </summary> private RequestDelegate next; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - RequestProcessingMiddleware(next) /// <summary> /// 생성자 /// </summary> /// <param name="next">다음 미들웨어</param> public RequestProcessingMiddleware(RequestDelegate next) { this.next = next; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 호출하기 - Invoke(context) /// <summary> /// 호출하기 /// </summary> /// <param name="context">HTTP 컨텍스트</param> /// <returns>태스크</returns> public async Task Invoke(HttpContext context) { if(context.Request.Path.ToString().ToLower() == "/secret") { context.Request.Path = new PathString("/"); } await next.Invoke(context); } #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; 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.AddControllersWithViews(); } #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("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseMiddleware<RequestProcessingMiddleware>(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints ( endpoints => { endpoints.MapControllerRoute ( name : "default", pattern : "{controller=Home}/{action=Index}/{id?}" ); } ); } #endregion } } |
TestProject.zip
■ UseMiddlewareExtensions 클래스의 UseMiddleware 확장 메소드를 사용해 컨텐트 생성 미들웨어를 등록하는 방법을 보여준다. ▶ ContentMiddleware.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
using Microsoft.AspNetCore.Http; using System.Threading.Tasks; namespace TestProject { /// <summary> /// 컨텐트 생성 미들웨어 /// </summary> public class ContentMiddleware { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 다음 미들웨어 /// </summary> private RequestDelegate next; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - ContentMiddleware(next) /// <summary> /// 생성자 /// </summary> /// <param name="next">다음 미들웨어</param> public ContentMiddleware(RequestDelegate next) { this.next = next; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 호출하기 - Invoke(context) /// <summary> /// 호출하기 /// </summary> /// <param name="context">HTTP 컨텍스트</param> /// <returns>태스크</returns> public async Task Invoke(HttpContext context) { if(context.Request.Path.ToString().ToLower() == "/hello") { await context.Response.WriteAsync("<h1>Hello from ContentMiddleware.</h1>"); } else { await next.Invoke(context); } } #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; 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.AddControllersWithViews(); } #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("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseMiddleware<ContentMiddleware>(); app.UseEndpoints ( endpoints => { endpoints.MapControllerRoute ( name : "default", pattern : "{controller=Home}/{action=Index}/{id?}" ); } ); } #endregion } } |
TestProject.zip
■ WebHostBuilderIISExtensions 클래스의 UseIISIntegration 확장 메소드를 사용해 IIS 웹 서버를 역전 프록시로 설정하는 방법을 보여준다. ▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; namespace TestProject { /// <summary> /// 프로그램 /// </summary> public class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 프로그램 시작하기 - Main(argumentArray) /// <summary> /// 프로그램 시작하기 /// </summary> /// <param name="argumentArray">인자 배열</param> public static void Main(string[] argumentArray) { CreateHostBuilder(argumentArray).Build().Run(); } #endregion #region 호스트 빌더 생성하기 - CreateHostBuilder(argumentArray) /// <summary> /// 호스트 빌더 생성하기 /// </summary> /// <param name="argumentArray">인자 배열</param> /// <returns>호스트 빌더</returns> public static IHostBuilder CreateHostBuilder(string[] argumentArray) => Host.CreateDefaultBuilder(argumentArray) .ConfigureWebHostDefaults ( builder => { builder.UseIISIntegration() .UseStartup<Startup>(); } ); #endregion } } |
TestProject.zip
■ HostingAbstractionsWebHostBuilderExtensions 클래스의 UseContentRoot 확장 메소드를 사용해 컨텐트 루트 경로를 설정하는 방법을 보여준다. ▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using System.IO; namespace TestProject { /// <summary> /// 프로그램 /// </summary> public class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 프로그램 시작하기 - Main(argumentArray) /// <summary> /// 프로그램 시작하기 /// </summary> /// <param name="argumentArray">인자 배열</param> public static void Main(string[] argumentArray) { CreateHostBuilder(argumentArray).Build().Run(); } #endregion #region 호스트 빌더 생성하기 - CreateHostBuilder(argumentArray) /// <summary> /// 호스트 빌더 생성하기 /// </summary> /// <param name="argumentArray">인자 배열</param> /// <returns>호스트 빌더</returns> public static IHostBuilder CreateHostBuilder(string[] argumentArray) => Host.CreateDefaultBuilder(argumentArray) .ConfigureWebHostDefaults ( builder => { string directory = Directory.GetCurrentDirectory(); builder.UseContentRoot(directory) .UseStartup<Startup>(); } ); #endregion } } |
▶ Controllers/HomeController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; namespace TestProject.Controllers { /// <summary> /// 홈 컨트롤러 /// </summary> public class HomeController : Controller { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 웹 호스트 환경 /// </summary> private IWebHostEnvironment environment; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - HomeController(environment) /// <summary> /// 생성자 /// </summary> /// <param name="environment">웹 호스트 환경</param> public HomeController(IWebHostEnvironment environment) { this.environment = environment; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 인덱스 페이지 처리하기 - Index() /// <summary> /// 인덱스 페이지 처리하기 /// </summary> /// <returns>액션 결과</returns> public IActionResult Index() { ViewData["WebRootPath" ] = this.environment.WebRootPath; ViewData["ContentRootPath"] = this.environment.ContentRootPath; return View(); } #endregion } } |
▶ Views/Home/Index.cshtml
|
<p>홈 인덱스 페이지</p> <hr /> <p>WebRootPath : @ViewData["WebRootPath"]</p> <p>ContentRootPath : @ViewData["ContentRootPath"]</p> |
더 읽기
■ dotnet tool install 명령을 사용해 Entity Framework Core를 업데이트하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을 실행한다.
더 읽기
■ dotnet ef 명령을 사용해 Entity Framework Core 버전을 확인하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을 실행한다.
더 읽기
■ dotnet ef 명령을 사용해 Entity Framework Core 설치 여부를 확인하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을
더 읽기
■ Identity 인증를 사용해 IdentityUser 객체에 커스텀 관리 항목을 추가하는 방법을 보여준다. (SQL SERVER 사용) ▶ TestProject.csproj
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0" /> <PackageReference Include="NETCore.MailKit" Version="2.0.3" /> </ItemGroup> <ItemGroup> <Folder Include="Migrations\" /> </ItemGroup> </Project> |
▶ appsettings.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
{ "MailAddress" : { "Server" : "smtp.live.com", "Port" : 587, "SenderName" : "sender", "SenderEmail" : "sender@hotmail.com", "Account" : "sender@hotmail.com", "Password" : "password", "Security" : true }, "Logging" : { "LogLevel" : { "Default" : "Information", "Microsoft" : "Warning", "Microsoft.Hosting.Lifetime" : "Information" } }, "AllowedHosts" : "*", "ConnectionStrings" : { "DefaultConnection" : "Server=(localdb)\\MSSQLLocalDB;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true" } } |
▶
더 읽기
■ Identity 인증를 사용해 IdentityUser 객체에 커스텀 관리 항목을 추가하는 방법을 보여준다. ▶ appsettings.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
{ "MailAddress" : { "Server" : "smtp.live.com", "Port" : 587, "SenderName" : "sender", "SenderEmail" : "sender@hotmail.com", "Account" : "sender@hotmail.com", "Password" : "password", "Security" : true }, "Logging" : { "LogLevel" : { "Default" : "Information", "Microsoft" : "Warning", "Microsoft.Hosting.Lifetime" : "Information" } }, "AllowedHosts" : "*" } |
▶ Data/DatabaseContext.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using TestProject.Models; namespace TestProject.Data { /// <summary> /// 데이터베이스 컨텍스트 /// </summary> public class DatabaseContext : IdentityDbContext<ApplicationUser> { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - DatabaseContext(options) /// <summary> /// 생성자 /// </summary> /// <param name="options">옵션</param> public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { } #endregion } } |
▶ Models/ApplicationUser.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
using Microsoft.AspNetCore.Identity; namespace TestProject.Models { /// <summary> /// 애플리케이션 사용자 /// </summary> public class ApplicationUser : IdentityUser { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 부서 - Department /// <summary> /// 부서 /// </summary> public string Department { get; set; } #endregion } } |
▶
더 읽기
■ IdentityServer4 액세스 토큰을 갱신하는 방법을 보여준다. [TestIdentityServer 프로젝트] ▶ Properties/launchSetting.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
{ "iisSettings" : { "windowsAuthentication" : false, "anonymousAuthentication" : true, "iisExpress" : { "applicationUrl" : "http://localhost:50000", "sslPort" : 44300 } }, "profiles" : { "IIS Express" : { "commandName" : "IISExpress", "launchBrowser" : true, "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } }, "TestAuthorizationServer" : { "commandName" : "Project", "launchBrowser" : true, "applicationUrl" : "https://localhost:5001;http://localhost:5000", "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } } } } |
▶ Configuration.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
using System.Collections.Generic; using IdentityModel; using IdentityServer4; using IdentityServer4.Models; namespace TestIdentityServer { /// <summary> /// 구성 /// </summary> public static class Configuration { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 신원 리소스 리스트 구하기 - GetIdentityResourceList() /// <summary> /// 신원 리소스 리스트 구하기 /// </summary> /// <returns>신원 리소스 리스트</returns> public static List<IdentityResource> GetIdentityResourceList() { return new List<IdentityResource>() { new IdentityResources.OpenId(), new IdentityResources.Profile() }; } #endregion #region API 범위 리스트 구하기 - GetAPIScopeList() /// <summary> /// API 범위 리스트 구하기 /// </summary> /// <returns>API 범위 리스트</returns> public static List<ApiScope> GetAPIScopeList() { return new List<ApiScope> { new ApiScope("API1", "API 1"), new ApiScope("API2", "API 2") }; } #endregion #region 클라이언트 리스트 구하기 - GetClientList() /// <summary> /// 클라이언트 리스트 구하기 /// </summary> /// <returns>클라이언트 리스트</returns> public static List<Client> GetClientList() { return new List<Client> { new Client { AllowedGrantTypes = GrantTypes.ClientCredentials, ClientId = "CLIENTID0002", ClientSecrets = { new Secret("CLIENTSECRET0002".ToSha256()) }, AllowedScopes = new List<string> { "API1" } }, new Client { AllowedGrantTypes = GrantTypes.Code, ClientId = "CLIENTID0003", ClientSecrets = { new Secret("CLIENTSECRET0003".ToSha256()) }, RedirectUris = { "https://localhost:44330/signin-oidc" }, AllowedScopes = new List<string> { "API1", "API2", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile }, RequireConsent = false, AllowOfflineAccess = true } }; } #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using TestIdentityServer.Data; namespace TestIdentityServer { /// <summary> /// 시작 /// </summary> public class Startup { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 서비스 컬렉션 구성하기 - ConfigureServices(services) /// <summary> /// 서비스 컬렉션 구성하기 /// </summary> /// <param name="services">서비스 컬렉션</param> public void ConfigureServices(IServiceCollection services) { services.AddDbContext<DatabaseContext>(options => { options.UseInMemoryDatabase("MemoryDB"); }); services.AddIdentity<IdentityUser, IdentityRole> ( options => { options.Password.RequiredLength = 4; options.Password.RequireDigit = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; } ) .AddEntityFrameworkStores<DatabaseContext>() .AddDefaultTokenProviders(); services.ConfigureApplicationCookie ( options => { options.Cookie.Name = "IdentityServer.Cookie"; options.LoginPath = "/Auth/Login"; } ); services.AddIdentityServer() .AddAspNetIdentity<IdentityUser>() .AddInMemoryIdentityResources(Configuration.GetIdentityResourceList()) .AddInMemoryApiScopes(Configuration.GetAPIScopeList()) .AddInMemoryClients(Configuration.GetClientList()) .AddDeveloperSigningCredential(); services.AddControllersWithViews(); } #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(); } app.UseRouting(); app.UseIdentityServer(); app.UseEndpoints ( endpoints => { endpoints.MapDefaultControllerRoute(); } ); } #endregion } } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace TestIdentityServer { /// <summary> /// 프로그램 /// </summary> public class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 프로그램 시작하기 - Main(argumentArray) /// <summary> /// 프로그램 시작하기 /// </summary> /// <param name="argumentArray">인자 배열</param> public static void Main(string[] argumentArray) { IHost host = CreateHostBuilder(argumentArray).Build(); using(IServiceScope scope = host.Services.CreateScope()) { UserManager<IdentityUser> userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>(); IdentityUser user = new IdentityUser("alice"); userManager.CreateAsync(user, "alice").GetAwaiter(); } host.Run(); } #endregion #region 호스트 빌더 생성하기 - CreateHostBuilder(argumentArray) /// <summary> /// 호스트 빌더 생성하기 /// </summary> /// <param name="argumentArray">인자 배열</param> /// <returns>호스트 빌더</returns> public static IHostBuilder CreateHostBuilder(string[] argumentArray) => Host.CreateDefaultBuilder(argumentArray) .ConfigureWebHostDefaults ( builder => { builder.UseStartup<Startup>(); } ); #endregion } } |
[TestAPIServer1
더 읽기
■ HeaderPropagationApplicationBuilderExtensions 클래스의 UseHeaderPropagation 확장 메소드를 사용해 헤더 전파 미들웨어를 추가하는 방법을 보여준다. ▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; 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.AddHttpClient("test").AddHeaderPropagation(); services.AddHeaderPropagation ( options => { options.Headers.Add("X-TraceId"); } ); services.AddControllersWithViews(); } #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("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseHeaderPropagation(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints ( endpoints => { endpoints.MapControllerRoute ( name : "default", pattern : "{controller=Home}/{action=Index}/{id?}" ); } ); } #endregion } } |
※ 설치 패키지 : Microsoft.AspNetCore.HeaderPropagation