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

 수많은 의존관계에 있는 JS 파일을 웹에 배포하는 것이 그리 쉬운일이 아닐겁니다.


이때 사용하는 것이 WebPack Module Bundler 입니다.


설치는 


npm install -g webpack


사용은 


webpack "WoojjaCustomer.js" "Bundle.js" --output-library='WoojjaLibrary'



webpack 에게 시작 JS 파일을 알려주면 참조관계에 맞추어 Bundle JS 파일을 생성해주며, WoojjaLibrary 라는 이름의 component 를 생성해줍니다.



HTML 에서의 사용은 


<script src="Bundle.js"></script>

<script>

var x = new WoojjaLibrary.Customer();

x.Add();

</script>


접근하는데도 편리하겠죠? 


행복한 고수되셔요~ ^^


woojja ))*

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














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

'Web > JavaScript' 카테고리의 다른 글

[JavaScript] WebPack  (0) 2017.10.09
[JavaScript] SystemJS  (0) 2017.10.08
[JavaScript] Interval, Timeout  (0) 2017.02.11
[JavaScript] Markup Insertion  (0) 2017.02.10
[JavaScript] Pop Up 차단 확인  (0) 2017.01.26
[JavaScript] Browser 탐지 스크립트  (0) 2017.01.26
Posted by woojja
TAG webpack


JavaScript 사용시 JavaScript 파일의 참조와는 상관없이 SystemJS 에게 시작 JS 파일을 알려주면 알아서 참조되는 JavaScript 파일을 Loading 해줍니다.


설치는 

npm install systemjs



사용법은 


<script src="system.js"></script>

<script>

SystemJS.import('./Customer.js')

.then(function(module){

var cust = new module.Customer();

cust.Add();

}).catch(function (err)

{ console.error(err); });;

</script>


SystemJS.import 에서 시작 JS 파일을 알려주고 있습니다.


행복한 고수되셔요. ^^


woojja ))*

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













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

'Web > JavaScript' 카테고리의 다른 글

[JavaScript] WebPack  (0) 2017.10.09
[JavaScript] SystemJS  (0) 2017.10.08
[JavaScript] Interval, Timeout  (0) 2017.02.11
[JavaScript] Markup Insertion  (0) 2017.02.10
[JavaScript] Pop Up 차단 확인  (0) 2017.01.26
[JavaScript] Browser 탐지 스크립트  (0) 2017.01.26
Posted by woojja
TAG SystemJS


tsc -v 을 통해서 TypeScript 의 Version 을 확인합니다.

헌데 Version 이 1.0.3 으로 낮아서 update 를 하려해보지만 

Update 는 오류메세지 없이 진행되지만 tsc -v 로 확인해보면 

Version 이 낮은 상태로 변경이 되지 않는 경우가 있습니다.


이런 경우  "C:\Program Files (x86)\Microsoft SDKs\TypeScript\" 폴더로 들어가 

"C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0" 폴더를 삭제해 줍니다.


저는 그냥 "1.0_" 로 폴더 명을 변경해 주었습니다.


그리고 tsc -v 로 확인하면 Version 이 올라간것을 확인 하실수 있을 겁니다.



행복한 고수되셔요~ ^^


woojja ))*

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













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

'Web > TypeScript' 카테고리의 다른 글

[TypeScript] TypeScript 의 version 이 변경되지 않을때...  (0) 2017.10.08
Posted by woojja



“Angular is an open source JavaScript framework which simplifies binding code between JavaScript

objects and HTML UI elements.”


Angular is created using typescript language.

So if you are doing development with Angular, typescript is the way to go ahead.

 

“TypeScript is a sugar-coated Object-oriented programming language over JavaScript.”


 

행복한 하루되셔요.


woojja ))*

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













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

'Web > Angular' 카테고리의 다른 글

[Angular] Angular is ...  (0) 2017.09.22
Posted by woojja

 

 

다음 글을 한글로 바꾸었습니다.

Getting Started with ASP.NET Web API 2 (C#)

많이 부족합니다. 참고만 하셔요 ~ ^^

 

ASP.NET Web API 2 시작하기 (C#)

by Mike Wasson

Download Completed Project

HTTP 단순히 web Page 만을 serving 하기 위한 프로토콜이 아닙니다. 서비스와 데이터를 노출하기 위한 API 구축하는데 강력한 Platform 이기도 합니다.

HTTP 간단하고 유연하며 Ubiquitous 합니다. 머리에 떠오르는 거의 모든 Platform 에는 HTTP Library 포함하고 있으므로 HTTP Service 브라우져를 포함한 모바일 기기, 전통적인 데스크탑 어플리케이션에 이르기 까지 광범위한 클라이언트까지 연결할 있습니다.

ASP.NET Web API .NET Framework 기반위에 Web API 구축하기 위한 Framework 입니다., Tutorial 에서는 ASP.NET Web API 사용하여 Product 목록을 반환하는 Web API 생성합니다.

 

Tutorial 에서 사용 된 Software Version

  • Web API 2

 

Web API Project 생성하기

Tutorial 에서 ASP.NET Web API 사용하여 Product 목록을 반환하는 Web API 생성합니다.

Front-end web page 는 jQuery 사용하여 결과를 표시합니다.

 

Visual Studio 시작하고 Start Page 에서 New Project 선택합니다. 또는 File Menu 에서 New 선택하고 Project 선택합니다.

Template 창에서 설치된 Templates 선택하고 Visual C# Node 확장합니다. Visual C# 아래에 Web 선택합니다. Project Template 목록에서 ASP.NET Web Application 선택합니다. Project Name "ProductsApp" 입력하고 OK 클릭합니다.

 

ASP.NET Project 대화상자에서 Empty template( 템플릿) 선택합니다.

"Add folders and core reference for"("폴더 핵심 참조 추가") 하단의 Web API Check 하고 OK 클릭합니다.

[!주목] "Web API" Template 사용하여 Web API Project 생성할 수도 있습니다.. Web API template ASP.NET MVC 사용하여 API Help Page 제공합니다. MVC 없이 Web API 작성하는 모습을 보여주기 위해 Empty template 사용합니다. 일반적으로 Web API 사용하기위해 ASP.NET MVC 알필요는 없습니다.

 

Model 추가하기

Model application 에서 Data 표현하는 객체입니다. ASP.NET Web API model JSON, XML 또는 다른 형식으로 자동적으로 직렬화해줍니다. 그리고 직렬화된 data HTTP Response Message Body 작성합니다. Client 직렬화된 형식을 읽을 있다면 Object Deserialize 있습니다. 대부분의 Client 들은 XML 이나 JSON Parsing 있습니다. 게다가 HTTP request Message Accept header 설정하여 원하는 format  표시하는 것도 가능합니다.

 

그럼, Product 나타내는 간단한 Model 생성하는 부터 시작해 봅시다.

Solution Explorer 아직 보이지 않는다면, View Menu 클릭하여 Solution Explorer 선택하십시오.

 

Models 폴더를 마우스 오른쪽 버튼으로 클릭합니다. 나타난 Context Menu 에서 Add 선택하고 Class 선택합니다.

 

Class Name 으로 "Product" 지정합니다. Product Class 다음 Properties 추가합니다.

namespace ProductsApp.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

 

 

Controller 추가하기

Web API 에서 Controller HTTP Request 처리하는 객체입니다. 이제 Product 목록 이나 지정한 ID 단일 Product 정보를 반환하는 Controller 추가합니다.

[!주목] ASP.NET MVC 사용해 본적이 있다면 이미 controller 익숙할 것입니다. Web API Controller MVC Controller 유사하지만 Controller class 대신에 ApiController Class 상속합니다.

 

Solution Explorer 에서  Controller folder 마우스 오른쪽 버튼을 이용하여 클릭합니다. Add 선택한 Controller 선택합니다.

 

Add Scaffold 대화상자에서 Web API Controller - Empty 선택합니다. Add 클릭합니다.

 

Add Controller 대화상자에서 Controller 이름을 ProductsController 지정합니다. Add 클릭합니다.

 

Scaffolding Controller folder ProductsController.cs 라는 이름의 파일을 생성합니다.

[!주목]Controller 파일들을 Controllers 라는 이름의 folder 넣지 않아도 됩니다. Folder 이름은 단지 Source 파일들을 구성하기위한 편리한 방법중 하나입니다.

파일이 아직 열려있지 않다면, 파일을 더블클릭하여 엽니다. 열린 파일의 코드를 다음의 코드로 대체합니다.

using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;

namespace ProductsApp.Controllers
{
    public class ProductsController : ApiController
    {
        Product[] products = new Product[]
        {
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
        };

        public IEnumerable<Product> GetAllProducts()
       
{
            return products;
        }

        public IHttpActionResult GetProduct(int id)
       
{
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }
    }
}

 

예제를 단순하게 유지하기 위해서 Products Controller Class 내부에 고정된 배열로 저장되어 있습니다. 물론 실제 application 에서는 database 다른 외부의 data source 부터 Query 하여 사용합니다.

 

Controller 에서는 Product 반환하는 두가지 Method 정의합니다.

  • GetAllProducts Method 는 Ienumerable<Product> 형식의 Product 전체 목록을 반환합니다.
  • GetProduct Method ID   단일 Product 조회합니다.

 

작동하는 Web API 이게 다입니다. Controller Method 하나 이상의 URL 일치합니다 :

 

Controller Method

URI

GetAllProducts

/api/products

GetProduct

/api/products/id

 

GetProduct Method URL id placeholder 입니다. 얘룰 둘어 ID 5 product 조회하는 URL api/products/5.입니다.

Web API HTTP request Controller method Route하는 방법에 대해서는 Routing in ASP.NET Web API 참조하십시오.

 

javascript jQuery web API 호출하기.

이번에는 Web API 호출하기위해 AJAX 사용하는 HTML page 추가합니다. AJAX 호출을 만들고 반환된 결과로 Page Update  하기 위해서 jQuery 사용합니다.

 

솔루션 탐색기에서 Project 오른쪽 마우스 버튼을 클릭하여 Add 선택하고 New Item 선택합니다.

 

New Item 대화상자에서 Visual C# 포함된 Web node 선택하고 HTML Page item 선택합니다. Page 이름은 "Index.html" 으로 지정합니다.

 

파일의 모든 내용을 다름 내용으로 바꿉니다 : 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Product App</title>
</head>
<body>

  <div>
    <h2>All Products</h2>
    <ul id="products" />
  </div>
  <div>
    <h2>Search by ID</h2>
    <input type="text" id="prodId" size="5" />
    <input type="button" value="Search" onclick="find();" />
    <p id="product" />
  </div>

  <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
  <script>
    var uri = 'api/products';

    $(document).ready(function () {
      // Send an AJAX request
      $.getJSON(uri)
          .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
              // Add a list item for the product.
              $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
          });
    });

    function formatItem(item) {
      return item.Name + ': $' + item.Price;
    }

    function find() {
      var id = $('#prodId').val();
      $.getJSON(uri + '/' + id)
          .done(function (data) {
            $('#product').text(formatItem(data));
          })
          .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
          });
    }
 
</script>
</body>
</html>

 

jQuery 가져오는 방법에는 몇가지방법이 있습니다. 예제에서는 Microsoft Ajax CDN 사용했습니다. http://jquery.com/ 에서도 다운로드 받을수 있으며, ASP.NET "Web API" project template 에도 jQuery 포함되어 있습니다.

 

Product 목록 가져오기

product 목록을 조회해오기 위해서 "/api/products" HTTP GET Request 보냅니다.

jQuery getJSON function AJAX request 보냅니다. response 에는 JSON 객체의 배열이 포함되어 있습니다. done function request 성공했을 호출될 callback 지정합니다. callback 에서 product 정보를 가지고 DOM update 합니다.

$(document).ready(function () {
    // Send an AJAX request
    $.getJSON(apiUrl)
        .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
                // Add a list item for the product.
                $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
        });
});

 

ID Product 정보 가져오기

ID Product 정보를 가져오기 위해서는 "/api/products/id" HTTP GET request 보냅니다. 여기서 id Product ID 입니다.

function find() {
    var id = $('#prodId').val();
    $.getJSON(apiUrl + '/' + id)
        .done(function (data) {
            $('#product').text(formatItem(data));
        })
        .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
        });
}

 

AJAX request 보내기 위해 이전과 동일하게 getJSON 호출합니다. 하지만 이번에는 request URI ID 포함시킵니다. request 부터 전달된 response 단일 Product 표현된 JSON 입니다.

 

Application 실행하기

 

F5 눌러 application debugging 시작합니다. 다음과 같이 web page 보여야 합니다 :

 

ID Project 조회하기 위해서는 ID 입력하고 Search 버튼을 클릭합니다.

 

유효하지 않은 ID 입력하면 server HTTP 오류를 반환합니다.

 

F12 사용하여 HTTP Request Response 내용 보기

HTTP Service 이용하는 작업을 HTTP Request Response Message 확인하는 것은 매우 유용합니다. Internet Explorer 9 F12 개발자도구를 사용하면 작업이 가능하다. Internet Explorer 9 에서 F12 툴러 도구를 엽니다. Network Tab 클릭하고  Start Capturing 누릅니다. 이제 Web page 돌아가서 F5 눌러 Web page 새로고침합니다. Internet Explorer browser web server 간의 traffic capture 합니다. summery page page 에서 일어난  모든 network traffic 보여줍니다.

 

상대경로 URI 중에서 "api/products/" 항목을 찾으십시요. 항목을 선택하고 Go to detail view 클릭합니다. 상세 View request response header body 있는 tab 있습니다. 예를 들어, Request headers Tab 클릭하면 Accept header 속에 client 요청한 "application/json" 확인할 있습니다.

 

Response body tab 클릭하면 product list 어떻게 JSON 으로 Serialized 되어 있는지 확인할 있습니다. 다른 browser 들고 유사한 기능을 가지고 있습니다. 다른 유용한 Tool 로는 Fiddler 있으며 web debugging proxy 입니다. Fiddler 사용하여 HTTP traffic 있으며. HTTP request 재구성하여 request HTTP header 완벽하게 제어할 있게 해줍니다.

 

Azure 에서 App 실행하기

완성된 site 실제 구동하는 web app 으로 실행되는 모습을 보는 것은 어떻습니까? 다음 버튼을 간단히 click 하는 것만으로 여러분의 Azure 계정에 앱의 전체 버전을 배포하는 것이 가능합니다.

Azure Solution 배포하려면 Azure 계정이 필요합니다. 계정을 가지고 있지 않다면, 다음과 같은 옵션을 사용할 있습니다 :

  • 무료로 Azure 계정을 여십시오 - 유료 Azure service 사용할 있는 credits 얻습니다. 모두 사용한 후에도 계정을 유지할 있으며 무료 Azure service 사용할 있습니다.
  • MSDN 구독자 혜택 활성화 - 여러분이 가진 MSDN subscription 매월 유료 Azure service 사용할 있는 credits 지급합니다.

 

다음 단계

 

 

 

 

 

행복한 고수되셔요~

 

woojja ))*

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

 

PS : OnoNote 에 썼다가 이쪽으로 옮기니 보여지는 글씨들이 맘에 안드네요. ㅡㅡ;

불편하셔도 이해해주셔요. ^^;

 

 













저작자 표시 비영리 변경 금지
신고
Posted by woojja
2017.09.07 15:53

 

 

Web API

 

하나씩 한글로 바꾸어 보려고요. ^^

 

행복한 고수되셔요~

 

woojja ))*

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

 













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

 

 

Framework Version 2 이후의 MVC와 Web API 간의 주된 차이점은 Web API handler 의 경우 HttpTaskAsynHandler 의 Subclass 인 반면 MVC 버전의 MvcHandler 는 IHttpAsyncHandler 를 직접 구현하였다.

 

HttpTaskAsyncHandler 는 Web API 2 에서 지원되는 .NET version 인 .NET 4.5 에만 있다.

 

동일한 ASP.NET process 내에서 MVC와 Web API 를 동시에 구동할 때 ASP.NET 은 HttpApplication을 사용하게된다.

Request 가 들어오면 MapRequestHandler event 에서 사용할 Http Handler 를 결정한다.

이 단계에서 route matching 이 일어나고 request 는 선택된 route 와 관련된 IRoutHandler 를 통해 이동하게된다.

 

IRouteHandler 의 유일한 목적은 request 를 처리(handle)할 수 있는 IHttpHandler 를 생성하는 것이다.

만일 IRouteHandler 가 HttpControllerRouteHandler (Web API route) 라면 Web API 경로가 선택되어 Request 는 HttpControllerHandler 에서 끝마치게되며, 반대로 Route Handler 가 MvcRouteHandler 라면 MVC 경로를 취하여 MvcHandler 로 이동한다.

 

 

(APRESS) ASP.NET Web API 2 Recipes 중에서...

 

 

행복한 고수되셔요. ^^*

 

 

woojja ))*

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

 

 

 













저작자 표시 비영리 변경 금지
신고
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

티스토리 툴바