'Web/ASP.NET Core'에 해당되는 글 3건

  1. 2017.10.27 [ASP.NET Core] Adding a view to an ASP.NET Core MVC app (3/10)
  2. 2017.07.10 [ASP.NET Core] MiddleWare
  3. 2017.06.11 [ASP.NET Core] Application Startup

 

Adding a view to an ASP.NET Core MVC app (3/10)

 

 

1. 시작 (원글 : Getting started)
2. Controller 추가하기 (원글 : Adding a controller)
3. View 추가하기 (원글 : Adding a view)
4. Model 추가하기 (원글 : Adding a model)
5. Working with SQL Server LocalDB
6. Controller methods and views
7. Adding Search
8. Adding a New Field
9. Adding Validation
10. Examining the Details and Delete methods

 

이 섹션에서 여러분은 client 에 응답할 HTML 을 생성하는 작업을 깔끔하게 캡슐화하는 Razor view template 을 사용하기 위해 HellowWorldController class 를 수정합니다.

여러분은 Razor 를 사용하는 view template file 을 생성합니다.

Razor 기반 View template 은 cshtml 확장자를 갖습니다.

C# 을 사용하여 HTML output 을 생성하는 우아한 방법을 제공합니다.

현재 index method 는 controller class 에서 hard-cord 된 string 의 message 를 반환합니다.

HelloWorldController class 의 index method 를 다음 코드로 변경합니다.

 

 

public IActionResult Index()
{
    return View();
}

 

진행되는 code 는 view object 를 반환합니다.

Browser 에 HTML 응답코드를 생성하기위해 view template 을 사용합니다.

위 index method 같은 Controller method (action method 로 알려진) 는 일반적으로 string과 같은 Primitive 한 형식이 아닌 IActionResult (또는 ActionResult 에서 파생된 class) 를 반환합니다.

Views Folder 를 오른쪽 클릭합니다., 그리고 Add > New folder 를 선택합니다. 그리고 folder 이름을 "HelloWorld" 로 지정합니다.

Views/HelloWorld folder 를 오른쪽 클릭합니다. 그리고 Add > New Item 을 선택합니다.

 

Add New Item - MvcMovie 대화창에서  

오른쪽 상단의 search 입력란에 view 를 입력합니다.

MVC View Page 를 Tap 합니다.

Name 입력란에 필요하다면 이름을 index.cshtml 로 변경합니다.

Add 를 Tap 합니다.

 

Add New Item dialog

 

Views/HelloWorld/index.cshtml Razor View 파일의 내용을 다음의 코드로 변경하십시오.

 

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

 

http://localhost:xxx?HelloWorld 로 이동하십시오.

HelloWorldController 의 index method 는 많은 일을 하지 않습니다. 구문을 실행하고 View(); 를 반환하는 함수를 지정하는데, Browser 에 보낼 응답을 render 하기 위해서 View template 을 사용해야 합니다.

View template file 의 이름을 명확하게 지정하지 않았기 때문에 MVC 는 기본적으로 Views/HelloWorld 폴더내의 index.cshtml view file 을 사용합니다.

아래의 이미지는 View 에 Hard Cording된 "Hello from our View Template!" 이라는 문자열을 보여줍니다.

 

 

Browser window

 

만약 여러분의 browser 창이 작다면( 예를들어, mobile device 처럼 ), Home, About, Contact 링크를 보기위해서 우측상단의 Bootstrap navigation button 을 toggle (tap)할 필요가 있습니다.

 

Browser window highlighting the Bootstrap navigation button

 

View 와 Layout page 변경하기

menu link (MvcMovie, Home, About) 를 Tap 합니다.

각 페이지는 동일한 menu layout 을 보여줍니다.

menu layout 은 Views/Shared/_Layout.cshtml file 에 구현되어 있습니다.

Views/Shared/_Layout.cshtml 파일을 여십시오.

 

Layout template 을 사용하면 여러분 사이트의 HTML container layout 를 한곳에서 지정할 수있으며 여러분 사이트의 여러페이지에 적용됩니다.

@RenderBody() Line 을 찾으십시오.

RenderBody 는 여러분이 만든 모든 view page 가 layout page 상에 보이도록 wrapping 된 Placeholder 입니다.

예를 들어, 만약 여러분이 About link 를 선택한다면, Views/Home/About.cshtml View 가 RenderBody method 내부에 rendering 됩니다.

 

Layout file 에서 Title 과 Menu link 변경

Title 요소의 내용을 변경하십시오.

아래 Highlight 된 코드처럼 Layout template 의 anchor text 를 "Movie App" 으로 변경하십시오. 그리고 Controller 를 Home 에서 Movies 로 변경하십시오.

 

참고 : ASP.NET Core 2.0 version 은 약간 다릅니다.

@inject ApplicationInsights 와 @Html.Raw(JavaScriptSnippet.FullScript) 는 포함되어 있지 않습니다.

 

 

@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>

    <environment names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
    @Html.Raw(JavaScriptSnippet.FullScript)
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-area="" asp-controller="Movies" asp-action="Index" class="navbar-brand">MvcMovie</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2017 - MvcMovie</p>
        </footer>
    </div>

    <environment names="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment names="Staging,Production">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>

 

 

경고

아직 Movies Controller 를 구현하지 않아서 해당 Link 를 클릭하면 404 (Not Found) 오류가 발생합니다. 

 

변경사항을 저장하고 About Link 를 Tap 하십시오.

browser tab 의 Title 에 About - Mvc Movie 대신에 About - Movie App 을 표시하는 방법에 주의하여 보십시오.

Contact Link 를 Tap 하여 Movie App 이 표시되는 것 또한 주의하여 보십시오.

Layout template 을 한번 변경하면 Site 의 전체 페이지에 새로운 링크와 새로운 title 이 반영하는 것이 가능했습니다.

Views/_ViewStart.cshtml file 을 검사하십시오.

 

@{
    Layout = "_Layout";
}

 

Views/_ViewStart.cshtml file 은 Views/shared/_Layout.cshtml file 을 각 View 에 전달합니다.

Layout property 에 다른 layout view 를 설정하거나  Null 을 설정하여 아무런 layout 을 사용하지 않도록 할 수 있습니다.

Index view 의  title 변경

Views/HelloWorld/Index.cshtml 을 엽니다. 두군데를 수정합니다.

browser 의 title 에 나타나는 text.

secondary header ( <h2> element )

코드의 어느부분을 변경하면 app 의 어느부분이 바뀌는지 약간의 차이점을 알수 있습니다.

 

 

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

 

 

위 코드의 ViewData["Title"] = "Movie List"; 는 ViewData dictionary 의 Title 속성을 "Movie List" 로 설정합니다.

Title 속성은 Layout page 의 <title> HTML element 에서 사용됩니다.

 

 

<title>@ViewData["Title"] - Movie App</title>

 

변경사항을 저장하고 http://localhost:xxxx/HelloWorld 로 이동하십시오.

browser title, Primary Heading, Secondary Heading 이 변경되었는지 주의해서 살펴보십시오.

(만약 browser 에서 변경사항을 볼 수 없다면 Cache 된 내용일 것입니다. browser 에서 Ctrl+F5 를 눌러 서버의 response 를 강제로 load 하십시오.)

browser title 이 ViewData["Title"]로 생성되어 index.cshtml template 에서 설정되고 추가적으로 " - Movie App" 이 Layout file 에서 추가됩니다.

또, Views/Shared/_Layout.cshtml view template 과 browser 로 보내진 single html response 가 어떻게 병합되어 index.cshtml view template 의 content 가 만들어지는지 주의하여 살펴보십시오.

Layout templates 를 변경하여 적용하면 application 의 모든 페이지 걸쳐 정말 쉽게 변경됩니다.

 

더 자세한 내용은 Layout 을 참조하십시오.

 

Movie List view

 

약간의 data ( 여기서는 "Hello from our View Template" 이라는 message) 는 Hard coding 되어 있습니다.

이 MVC application 에는 "V" (view) 가 있고 "C" (controller) 를 만들었지만 아직 "M" (model) 은 없습니다.

 

Controller 에서 View 로 Data 전달하기

Controller 의 actions 는 들어오는 (incoming) URL request 에 대한 response 에서 호출됩니다.

controller class 는 들어오는 browser request 를 처리하는 코드를 작성하는 곳입니다.

controller 는 data source 로 부터 data 를 retrieve 하고 browser 에 돌려보낼 response 의 type 을 결정합니다.

View template 은 controller 에서 browser 로 보내질 HTML response 를 생성하고 형식을 지정할 수 있습니다.

controller 는 view template 이 response 를 rendering 하기위해 요구되는 data 를 제공해야할 책임이 있습니다.

 

모범 사례 : View template 은 business logic 을 수행하거나 database 와 직접 상호작용을 하면 안됩니다.

대신 view template 은 오직 controller 가 view 만들 위해 제공하는 data 와 작업해야합니다.

이 관심의 분리( "separation of concerns" ) 를 유지하면 여러분의 코드를 깨끗하고, 테스트 가능하고 유지보수가능하도록 하는데 도움이 됩니다.

현재 HelloWorldController class 의 Welcome method 는 name 과 ID 를 매개변수로 취하여 browser 로 값을 직접 출력합니다.

controller 가 response 를 string 으로 rendering 하도록 하기보다. controller 가 view template 을 대신 사용하도록 변경합시다.

 

view template 은 동적 response 를 생성합니다. 이 것은 response 를 생성하기 위해서 적절한 bit 의 data 를 controller 에서 view 로 전달해야할 필요가 있다는 것을 의미합니다.

view template 이 필요한 data 를 controller 에서 dynamic data( parameters) 인  view template 이 접근 가능한 ViewData dictionary 에 담음으로써 이 작업이 가능합니다.

HelloWorldController.cs file 로 돌아가서 ViewData dictionary 에 Message 와 NumTimes 를 추가하도록 Welcome method 를 변경합니다.

ViewData dictionary 는 dynamic object 입니다. 즉 여러분이 원하는 것은 어떤 것도 집어 넣을 수 있습니다.

ViewData object 는 여러분이 그 안에 무언가를 넣기 전까지 정의된 속성이 없습니다.

MVC model binding system 은 address bar 에 적힌 query string 에서  이름있는 매개변수( name 과 numTimes )를 추출하여 여러분이 만든 method 의 parameter 로 자동적으로 mapping 합니다.

완전한 HelloWorldController.cs 파일의 내용은 다음과 같습니다.

 

 

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Welcome(string name, int numTimes = 1)
        {
            ViewData["Message"] = "Hello " + name;
            ViewData["NumTimes"] = numTimes;

            return View();
        }
    }
}

 

ViewData Dictionary 객체는 View 에 전달할 data 를 포함하고 있습니다.

Views/HelloWorld/Welcome.cshtml 라는 이름의 Welcome view template 을 생성하십시오.

Welcome.cshtml view template 내에 "Hello " NumTimes 를 표시할 Loop 를 생성합니다.

아래 코드로 Views/Helloworld/Welcome.cshtml 의 내용을 변경합니다.

 

 

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul> 

 

변경사항을 저장하고 다음 URL 로 이동하십시오.
http://localhost:xxxx/HelloWorld/Welcome?name=Rick&numtimes=4

Data 를 URL 에서 가져와서  MVC model binder 를 이용하여 controller 에 전달합니다.

controller 는 data 를 ViewData dictionary 에 packages 하고 View 에 그  Object 를 전달합니다.

그 다음 view 는 HTML data 를 browser 에 render 합니다.

 

 

About view showing a Welcome label and the phrase Hello Rick shown four times

 

위 sample 에서 controller 로 부터 view 로 data 를 전달하기위해서 ViewData Dictionary 를 사용했습니다.

다음 tutorial 에서는 controller 에서 view 로 data 를 전달하기위해서 view model 을 사용합니다.

data 를 전달하는 view model 접근 (approach) 은 일반적으로 ViewData dictionary 접근 보다 훨씬 더 좋습니다.

자세한 사항은 ViewModel vs ViewData vs ViewBag vs TempData vs Session in MVC 를 참조하십시오.

그럼, 여기서 M 은 model 을 말하는 것이지 database 를 의미하지 않습니다.

배운 것을 바탕으로 Movie database 를 생성해 봅시다.

 

 

 

이상입니다.

번역?이 이상하고 맘에 들지 않지만 참고로 보시기 바랍니다.

 

 

 

행복한 고수되셔요.

 

 

woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\













저작자 표시 비영리 변경 금지
신고

'Web > ASP.NET Core' 카테고리의 다른 글

[ASP.NET Core] Adding a view to an ASP.NET Core MVC app (3/10)  (0) 2017.10.27
[ASP.NET Core] MiddleWare  (0) 2017.07.10
[ASP.NET Core] Application Startup  (0) 2017.06.11
Posted by woojja

다음은 Middleware 의 내용을 번역했습니다.

번역이 많이 부족합니다. 참고로만 사용하셔요 ^^;

 

 

ASP.NET Core 미들웨어 기초

 

 

미들웨어란 무엇인가?
미들웨어란 Request와 Response 를 처리하기위해서 Pipeline 으로 조립된 소프트웨어다.
파이프라인에서 각 구성요소는 Request 를 다음 구성요소로 전달할지 여부를 결정하고, 파이프라인에서 다음 구성요소가 호출되기 이전, 이후에 특정 Action 을 수행하는 것이 가능하다.
Request delegate(요청 대리자, 위임자) 들은 Request Pipelie 을 구성하는데 사용된다.
Request delegate 들은 각 HTTP Request 를 처리한다.


 

Request delegate 는 IApplicationBuilder 인스턴스에서 Run, Map Use 확장 메서드로 구성되며  Startup클래스의 Configure 메서드로 전달된다.
개별적인 Request delegate 는 anonymous(익명) 메서드 (in-line middleware 라 불리는) 로서 in-line 에서 지정하거나 재사용가능한 클래스내에서 정의하는 것이 가능하다.
이런 재사용가능한 클래스와 인라인 익명 메서드는 미들웨어 이거나 미들웨어 구성요소다.
Request pipeline 의 각 미들웨어 구성요소는 pipeline 내에서 다음 구성요소를 호출하거나 적절한 경우 연결(Chain)을 끊는다.

 

Migrating HTTP Modules to Middleware 에서는 ASP.NET Core 와 이전 버전에서의 Request Pipeline 의 차이점에 대해 설명하고 더 많은 Middleware 예제를 제공한다.

IApplicationBuilder를 사용하여 미들웨어 파이프 라인 만들기
ASP.NET Core Request Pipeline 은 Request Delegate 들의 순서로 구성되며 Diagram에서 보듯이 차례대로 호출된다. (검정색 화살표 방향으로 실행이 진행된다.):

 


각 Delegate 는 다음 Delegate 가 실행되기 전후에 작업을 수행하는 것이 가능하다.
Delegate 는 또한 다음 Delegate 로 Request 를 전달할지 결정하는 것이 가능하며 이것을 Request Pipeline 을 단락(Short-circuiting)시킨다 라고 부른다.
Short-Circuiting 은 불필요한 작업을 피할 수 있기 때문에 종종 바람직하다.
예를 들어, 정적파일 Middleware 는 정적파일을 작성하기위한 Request 를 반환하거나 Pipeline 의 나머지 작업을 Short-Circuiting 하는 것이 가능하다.
Exception-handling Delegate 는 Pipeline 의 초기에 호출될 필요가 있으며, 그 결과로 Pipeline 이후단계에서 Exception 을 Catch 하는 것이 가능하다.

가장 단순하고도 실행가능한 ASP.NET Core App은 모든 Request를 처리하는 단일 Request delegate 를 구성한다.
이 경우 실제 Request Pipeline 을 포함하지 않는다.
대신 모든 HTTP Request 에 대해 Response 로 단일 anonymous function 이 호출된다.

 

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, World!");
        });
    }
}


첫번째 app.Run Delegate 는 Pipeline 을 종료한다.
app.Use 을 사용하여 여러 Request Delegate 들을 연결하는 것이 가능하다.
pipeline 에서 next Parameter 는 다음 Delegate 를 나타낸다.(next Parameter 를 호출하지 않음으로써 Pipeline 을 Short-Circuit 가능하다는 점을 기억하라.)
이 예제처럼 다음 Delegate 전후에 Action 을 전형적으로 수행하는 것이 가능하다.

 

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });
 
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

 

경고
Response 를 Client 에 전송한 후 next.Invoke 를 호출하지 말 것.
Response 가 시작된 이후에 HttpResponse 를 변경하면 exception 을 발생한다.
예를 들어 headers, status code등의 구성을 변경하는 작업은 exception을 발생한다.
next를 호출한 이후에 Response body 를 작성하라 : 
    protocol violation 의 원인이 될 수 있다. 예를 들어 content-length 보다 더 작성하는
    body format 을 손상할 수도 있다. 예를 들어 CSS 파일에 HTML footer 를 작성하는

HttpResponse.HasStarted 는 Header 가 보내졌는지 그리고/혹은 body 가 작성되었는지 알 수 있는 유용한 Hint 다.

 

순서정하기

Configure method 에 추가된 Middleware 구성요소의 순서는 Request 에서 호출되는 순서를 정의하며,
Response 의 역순이다.
이 순서는 보안, 성능, 기능에 중요하다.

(아래 보이는) Configure mathod 는 다음 Middleware 구성요소를 추가하고 있다.

1. Exception/error handling
2. Static file server
3. 인증
4. MVC

 

public void Configure(IApplicationBuilder app)
{
    app.UseExceptionHandler("/Home/Error"); // Call first to catch exceptions
                                            // thrown in the following middleware.
 
    app.UseStaticFiles();                   // Return static files and end pipeline.
 
    app.UseIdentity();                     // Authenticate before you access
                                           // secure resources.
 
    app.UseMvcWithDefaultRoute();          // Add MVC to the request pipeline.
}


 

위 코드에서 UseExceptionHandler 는 Pipeline 에 첫번째로 추가된 Middleware Component 로 이후 호출에서 발생하는 모든 exception 을 catch한다.
호출된 Static file Middleware Pipeline 의 초기에 호출되어 나머지 component를 거치지 않고도 Request 와 short-circuit 를 처리하는 것이 가능하다.
Static file Middleware 는 권한 Check 기능을 제공하지 않는다.
wwwroot 아래에 있는 파일들을 포함하여 Static file Middleware 에 의해 제공하는 모든 파일은 공개적으로 사용가능하다.
static file 의 보안 방법에 대해서는 Working with static files 를 참고하라.

만약 Request 가 static file middleware 에 의해 처리되지 않으면 인증을 수행하는 Identity middleware(app.UseIdentity) 로 전달된다.
Identity 는 인증되지 않는 request 를 short-circuit 하지 않는다.
Identity 가 request를 인증한다고 하더라고 권한부여(그리고 거부) 은 MVC 가 특정 Controller 와 Action 를 선택한 이후에만 나타난다.

다음 예제는   static file 이 Response 압축 Middleware 이전에 static file middleware 에 의해 처리되도록하는 middleware 의 순서를 정하는 모습을 보여준다.
이 middleware의 순서에서 보면 static file 은 압축되지 않는다.
UseMvcWithDefaultRoute 의 MVC response 는 압축이 가능하다.

 

 

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();         // Static files not compressed
                                  // by middleware.
    app.UseResponseCompression();
    app.UseMvcWithDefaultRoute();
}

 

 

Run, Map, 그리고 Use

Run, Map, 그리고 Use를 사용하여 HTTP pipeline 을 구성한다.
Run method 는 pipeline을 short-circuit 한다.(즉, next request delegate 를 호출하지 않는다.)
Run 은 규칙이며, 일부 middleware component 는 pipeline 의 마지막에 실행하는 Run[Middleware] method 를 노출할 수도 있다.
Map* extention 은 pipeline 을 분기(branch)하기 위한 규칙으로 사용한다.
Map 은 주어진 request 경로와 일치하는 것을 기반으로 request pipeline 을 분기한다.
만약 request 경로가 주어진 경로로 시작한다면 분기는 실행된다.

 

 

public class Startup
{
    private static void HandleMapTest1(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 1");
        });
    }
 
    private static void HandleMapTest2(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 2");
        });
    }
 
    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1", HandleMapTest1);
 
        app.Map("/map2", HandleMapTest2);
 
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
        });
    }
}


다음 표는 이전코드를 사용한  http://localhost:1234 의  Request 와 Response 를 보여준다.

 

 Request

 Response

 localhost:1234

 Hello from non-Map delegate.

 localhost:1234/map1

 Map Test 1

 localhost:1234/map2

 Map Test 2

 localhost:1234/map3

 Hello from non-Map delegate.

 

 

Map 이 사용되면 일치하는 경로 segment 는 HttpRequest.Path  에서 제거되고 각 request 의 HttpRequest.PathBase 에 추가된다.
MapWhen 은 주어진 predicate 의 결과를 기반으로 result pipeline 을 분기한다.
Func<HttpContext, bool> type 의 모든 predicate 는 request를 Pipeline 의 새로운 분기에 map 하는데 사용하는 것이 가능하다.
다음 예제에서 predicate 는 Query String 에  branch 가 variable 로 포함되어 있는지 검색하기 위해서 사용된다.

 

public class Startup
{
    private static void HandleBranch(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            var branchVer = context.Request.Query["branch"];
            await context.Response.WriteAsync($"Branch used = {branchVer}");
        });
    }
 
    public void Configure(IApplicationBuilder app)
    {
        app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
                               HandleBranch);
 
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
        });
    }
}

 

 

다음 표는 이전코드를 사용한  http://localhost:1234 의  Request 와 Response 를 보여준다.

 

 Request

 Response

 localhost:1234

 Hello from non-Map delegate.

 localhost:1234/?branch=master

 Branch used = master

 

 

다음 예처럼  Map 은 nesting 을 지원한다.:

 

app.Map("/level1", level1App => {
       level1App.Map("/level2a", level2AApp => {
           // "/level1/level2a"
           //...
       });
       level1App.Map("/level2b", level2BApp => {
           // "/level1/level2b"
           //...
       });
   });

 

 

다음 예제 처럼 Map 은 한번에 다양한 segments 또한 일치(match)시키는데 사용하는 것도 가능하다.:

 

app.Map("/level1/level2", HandleMultiSeg);

 

 

 

내장(Built-in) Middleware

ASP.NET Core 에는 다음 미들웨어 구성 요소들이 들어 있다.

 

 Middleware   

 설명

 Authentication

 인증 지원을 제공한다.

 CORS

 Cross-Origin 자원공유 를 구성한다.

 Response Cahching

 Response Caching 을 위한 지원을 제공한다.

 Response Compressing

 Response 압축을 위한 지원을 제공한다.

 Routing

 request Route를 정의하고 제한한다.

 Session 

 User Session 관리를 위한 지원을 제공한다.

 Static Files

 Static file과 directory Browsing 을 위한 지원을 제공한다.

 URL Rewriting Middleware

 URL rewriting 과 request 의 redirecting 을 위한 지원을 제공한다.

 


Middleware 작성하기
Middleware 는 일반적으로 class 내에서 encapsulate 되어있고 extention method 로 노출된다.
다음은 Query string 으로 부터 현재 request 의 문화권을 설정하는 Middleware 로 살펴보기 바란다.

 

 

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use((context, next) =>
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);
 
                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;
            }
 
            // Call the next delegate/middleware in the pipeline
            return next();
        });
 
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });
 
    }
}

 

 

참고 위의 Sample Code 는 middleware component 를 생성하것을 시연하는데 사용된다.
ASP.NET Core 의  내장 localization 에 관해서는 Globalization 과 Localization 을 참고하라.

 

예를 들어, http://localhost:7997/?culture=no 와 같이 culture(문화권 코드)를 전달하여 middleware 를 테스트하는 것이 가능하다.

 



다음 code 는 class 에 middleware delegate 가 Class 로 이동한다.

 

 

using Microsoft.AspNetCore.Http;
using System.Globalization;
using System.Threading.Tasks;
 
namespace Culture
{
    public class RequestCultureMiddleware
    {
        private readonly RequestDelegate _next;
 
        public RequestCultureMiddleware(RequestDelegate next)
        {
            _next = next;
        }
 
        public Task Invoke(HttpContext context)
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);
 
                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;
 
            }
 
            // Call the next delegate/middleware in the pipeline
            return this._next(context);
        }
    }
}

 

 

다음 extension method 는 IApplicationBuilder 를 통해서 middleware 를 노출한다.:

 

using Microsoft.AspNetCore.Builder;
 
namespace Culture
{
    public static class RequestCultureMiddlewareExtensions
    {
        public static IApplicationBuilder UseRequestCulture(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<RequestCultureMiddleware>();
        }
    }
}

 

 

The following code calls the middleware from Configure:

 

 

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRequestCulture();
 
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });
 
    }
}

 

 

Middleware 는 Constructor 에 의존성(dependencies)를 노출함으로써 명시적 의존성 원칙(Explicit Dependencies Principle) 을 따라야한다.
Middleware 는 Application lifetime 당 한번 생성된다.
Request 내에서  Middleware와 함께 service 를 공유할 필요가 있다면 아래 Pre-request dependency 를 참고하라.
Middleware component 는 constructor parameter 를 사용하여 dependecy injection으로 부터 자신의 dependency 를 해결하는 것이 가능하다.
UseMiddleware<T> 는 추가 parameter 를 직접 허용하는 것도 가능하다.


Per-request dependencies
middleware 가 request 당 생성되는 것이 아닌 app startup 에 생성되었기 때문에 각 request 가 진행되는 동안 middleware constructor 가 사용하는 scoped lifetime service 는 다른 dependency-injected type 과 공유되지 않는다. 
만약 scoped service 를 여러분이 생성한 middleware 와 다른 Type 간에 공유해야만 한다면
이 service 들을 Invoke method 의 Signature 에 추가하라.
Invoke method 는 dependency injection 에 의해 채워지는 추가 parameter 를 수락하는 것이 가능하다.

 

 

public class MyMiddleware
{
    private readonly RequestDelegate _next;
 
    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
 
    public async Task Invoke(HttpContext httpContext, IMyScopedService svc)
    {
        svc.MyProperty = 1000;
        await _next(httpContext);
    }
}

 

 

Resources
· Sample code used in this doc
· Migrating HTTP Modules to Middleware
· Application Startup
· Request Features

 

 

 

 

행복한 고수되십시요.

 

woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\













저작자 표시 비영리 변경 금지
신고

'Web > ASP.NET Core' 카테고리의 다른 글

[ASP.NET Core] Adding a view to an ASP.NET Core MVC app (3/10)  (0) 2017.10.27
[ASP.NET Core] MiddleWare  (0) 2017.07.10
[ASP.NET Core] Application Startup  (0) 2017.06.11
Posted by woojja

다음은 Application Startup in ASP.NET Core hDocs.microsoft.com/en-us/aspnet/core/fundamentals/startup) 의 내용을 번역했습니다.

 

.

 

 

Application Startup in ASP.NET Core

 

Startup Class 는 응용 프로그램에 대한 모든 Request 를 처리하는 Request pipeline을 구성한다.

Startup Class

ASP.NET Core Apps 는 Startup class 를 필요로한다.. 관례상 Startup class 는 "Startup" 이라 부른다.

Main program WebHostBuilderExtensions 의  UseStartup<Tstartup> method 내에 startup class 이름을 지정한다.

 

다양한 환경에 대해 별도의 Startup class 를 구성하는 것도 가능하며, runtime 이 그 중 적합한 하나를 선택하게된다.

WebHost Configuration 이나 Option 에서 StartAssembly 를 지정한다면 Hosting 은 지정한 startup assembly 를  Load 하고 Startup 이나 Startup[Environment] Type 을 검색한다.

 

StartupLoader 의 FindStartupType다양한 환경에서의 작업 (Working with multiple environment) 을 참조하자.

UseStartup<TStartup> 를 사용한 접근을 권장한다.

 

Startup class 의 생성자는 dependency injection 을 통해 제공하는 종속성을 수락하는 작업이 가능하다.

IHostingEnvironment 를 사용한 Configuration 소스를 구성하는 작업이 가능하고, ILoggerFactory 를 사용하여  Logging Provider 를 구성하는 작업이 가능하다.

 

Startup class 는 Configure Method 를 반드시 포함해야하며 선택적으로 ConfigureServices Method 를 포함하는 것이 가능하다. 이 두 Method 는 Application 이 시작할 때 호출된다.

이 Class 는 이 Method 의 환경별 (environment-specific) 버전을 포함하는 것 또한 가능하다. 

 

Application startup 동안 예외처리 에 대해 배워보자.

 


Configure Method


Configure Method 는 ASP.NET application 이 HTTP Request 에 대해 Respond 하는 방법을 지정하는데 사용한다. request pipeline 은 dependency injection 에 의해 제공되는 IApplicationBuilder 에 추가되는 middleware  를 추가하므로써 구성된다.

 

default web site template 를 이용한 다음 예제에서 몇가지 확장 Method 들이 BrowserLink, 오류페이지, 정적파일, ASP.NET MVC, Identity 들을 지원하는 pipeline 을 구성하는데 사용된다.

 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
 
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }
 
    app.UseStaticFiles();
 
    app.UseIdentity();
 
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

 

각 Use 확장 메소드는 request pipeline 에 middleware component 를 추가한다.

예를 들어, UseMvc 확장 메서드는 routing middleware 를  request pipeline 에 추가하고 MVC 를 기본 handler로 구성한다.


IApplicationBuilder를 사용하는 방법에 대한 자세한 정보는 Middleware 를 살펴보자.

IHostingEnvironment 와 ILoggerFactory와 같은 추가적인 서비스도 method signature 에 지정할 수 있으며, 이 경우 이 서비스들은 사용가능하다면 삽입(injected)될 것이다.

ConfigureServices method

ConfigureServices method 는 선택 사항이다. 하지만 사용될 경우 runtime 에 의해 Configure method 보다 먼저 호출된다. (일부 기능은 request pipeline 에 연결되기 전에 추가된다).

Configuration option 은 이 method 에 설정된다.


실질적인 Setup 이 필요한 기능들은 IServiceCollection 의 Add[Service] Extension method 다.

default web site template 를 이용한 다음 예제는  Entity Framwork, Identity, MVC 를 위한 Service 를 사용하기위해 app 을 구성한다.

 

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
 
    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();
 
    services.AddMvc();
 
    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

 

service container 에 서비스를 추가하는 작업은 dependency injection 을 통해 application 내에서 Service 를 사용할 수 있다.

 

Startup 에서 사용가능한 Service

 

ASP.NET Core 의 dependency injection 은  application 의 startup 동안 여러 application service 를 제공한다.

Startup class 의 생성자나 Startup class 의 Configure 나 ConfigureService method 중 한 method 의 parameter 로 적당한 Interface 를 추가함으로써 이런 Service 를 요청하는 것이 가능하다.

 

Startup class 의 각 method 를 호출되는 순서대로 살펴보면, 다음 Service 들이 parameter 로 요청될 것이다.

• Constructor 에서 : IHostingEnvironment, ILoggerFactory
• ConfigureServices method에서 : IServiceCollection
• Configure method 에서 : IApplicationBuilder, IHostingEnvironment, ILoggerFactory, IApplicationLifetime

 

추가 자료

 

이제 제 공부차원에서 https://docs.microsoft.com/en-us/aspnet/core 에 있는 내용들을 하나씩 올려보려고 합니다.

 

행복한 고수되십시요.

 

woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

 

 













저작자 표시 비영리 변경 금지
신고

'Web > ASP.NET Core' 카테고리의 다른 글

[ASP.NET Core] Adding a view to an ASP.NET Core MVC app (3/10)  (0) 2017.10.27
[ASP.NET Core] MiddleWare  (0) 2017.07.10
[ASP.NET Core] Application Startup  (0) 2017.06.11
Posted by woojja
이전버튼 1 이전버튼

티스토리 툴바