Transcript ASP.NET MVC

ASP.NET
Model-View-Controller
preview 3
MS P&P Study 자료
최상호
[email protected]
목차
1. ASP.NET MVC 살펴보기
1.
MVC 프레임워크와 애플리케이션 구조
2.
3.
4.
MVC 애플리케이션 실행 절차 이해하기
컨트롤러와 컨트롤러 액션
뷰와 뷰 렌더링
2. ASP.NET 라우팅
1.
2.
3.
4.
ASP.NET Routing .vs. URL Rewriting
URL 라우트 정의하기
다수 개의 URL 파라미터 처리
라우트에 제약 사항 걸기
3. Action Filter
1.
2.
3.
Action Filter의 구조
Action Filter 구현하기
Action Filter 적용하기
2
Page Controller 패턴 사용
Front Controller 패턴 사용
http://dotnetslackers.com/articles/aspnet/AnArchit
ecturalViewOfTheASPNETMVCFramework.aspx
3
Prerequisite
• MVC 패턴
• Page Controller 패턴
• Front Controller 패턴
• ASP.NET MVC Preview 3 설치하기
4
Prerequisite > ASP.NET MVC 설치하기
• ASP.NET MVC Preview 3 설치하기
• http://www.microsoft.com/downloads/details.aspx?FamilyI
d=92F2A8F0-9243-4697-8F9AFCF6BC9F66AB&displaylang=en
5
1. ASP.NET MVC Overview
• ASP.NET MVC
– 기존의 ASP.NET에 통합되어 동작
– 경량 프레임워크
– 테스트가 매우 용이한 프리젠테이션 프레임워크
• MVC 기반의 웹 애플리케이션 구현
– 다음의 기술 중에 하나를 택해서 만들 수 있다.
• ASP.NET Web Form
• ASP.NET MVC
– 프로젝트의 규모와 상황에 따라 적절한 방법을 택할 뿐이며 ASP.NET MVC가
기존의 ASP.NET Web Form 기반의 개발 방식보다 기술적으로 낫다는 의미는
아니다.
6
1. ASP.NET MVC Overview
• Model
– 애플리케이션의 데이터 도메인과 관련된 로직을 구현하는 부분
– 모델의 상태를 읽고 쓰는 작업을 보통 D/B를 통해 수행한다.
– 소규모 애플리케이션의 경우, Model이 물리적으로 따로 존재하지 않고 data
set 등의 개념적인 형태로 존재하여 Model의 역할을 수행하기도 한다.
• View
– Model의 데이터를 이용해서 애플리케이션의 UI를 표시하는 컴포넌트
• Controller
– 사용자의 입력과 행동을 처리하고, Model과의 작업을 진행하고, 화면 UI에
렌더링할 View를 선택한다.
7
1. ASP.NET MVC Overview
• MVC 패턴
– 서로 다른 로직(input/business/UI)들로 구성된 애플리케이션을 구축함으로
써 모듈마다 약한 결합성(loose coupling)을 갖게 하여 병행 개발이 가능하고
애플리케이션의 복잡성을 관리할 수 있게 한다.
– 분리된 각 모듈들은 개별적인 테스트가 용이해진다.
Application
View
UI Logic
Controller
Input Logic
Business Logic
Model
8
1. ASP.NET MVC Overview
• 웹 애플리케이션 개발 방식 비교
ASP.NET MVC 기반
ASP.NET 웹 폼 기반
애플리케이션
모델 구조
모델,뷰,컨트롤러 기반
state를 유지하는 이벤트 모
델
적용 패턴
Front controller 패턴
Page Controller 패턴
view state나 서버 기반의
폼을 사용하지 않기 때문에
애플리케이션의 행위를 완전
히 다룰 수 있다.
view state나 서버 기반의 폼
을 사용하여 state 정보의 관
리가 용이하다.
State 사용 여부
개발 조직
개발자와 웹 디자이너로 구성 보다 소규모의 팀에서 다수의
된 큰 규모의 개발팀에 적합
컴포넌트들을 빠르게 개발할
하다.
때 적합하다.
테스트 기반 개발(TDD)에 보
다 적합하다.
모듈 별 관리가 용이해 복잡
성 관리가 용이
컴포넌트가 서로 강하게 통합
/결합되어 있어 MVC 애플리
케이션보다 코드가 적고 덜
복잡하다.
9
1. ASP.NET MVC Overview
• ASP.NET MVC의 주요 특징(1/2)
1. 테스트 용이성
• 각 로직별로 모듈이 분리되어 있어 테스트가 매우 용이하다.
• 인터페이스 기반의 MVC 프레임워크는 Mock Object를 사용하여 테스트
할 수 있다.
• ASP.NET 런타임 상에서 컨트롤러를 실행하지 않아도 단위 테스트가 가
능하다.
• .NET Framework 에서 동작하는 어떤 단위 테스트 프레임과도 사용이
가능하다.
2. 확장과 플러그인이 용이한 프레임워크 구조
• View engine, URL 라우팅 정책, action-method 파라미터 직렬화 등의
컴포넌트들을 손쉽게 교체,커스터마이징 가능
• Dependency Injection(DI), IoC 컨테이너 모델을 지원한다.
3. 강력한 URL 매핑 컴포넌트
• URL에 파일 확장자(.aspx)가 포함될 필요없이 직관적으로 사용 가능.
• SEO 및 REST 에 적합한 URL 명명 패턴을 지원한다.
10
1. ASP.NET MVC Overview
• ASP.NET MVC의 주요 특징(21/2)
4. 기존의 markup 계속 지원
• .aspx, .ascx, .master 파일 등에서 사용하던 markup을 그대로 사용할
수 있다.
• Ex) nested master pages, in-line expressions(<%= %>),
declarative server controls, templates, data-binding,
localization,..
5. 기존의 ASP.NET 기능 그대로 지원
• Forms/windows authentication, URL authorization, membership
and roles,output and data caching, session and profile state
management, health monitoring, configuration system, the
provider architecgture.
11
1.1 MVC 프레임워크와 애플리케이션 구조
• Controller
– Controller 클래스 :
• 사용자 입력/액션 등의 요청(request)를 처리
• 사용자 입력에 따른 적절한 애플리케이션과 데이터 로직을 수행한다.
• URL Mapping
– ASP.NET MVC 프레임워크에는 URL을 ASP.NET 페이지 또는 핸들러로 매핑
하지 않고 컨트롤러 클래스로 매핑하는 유연한 URL 라우팅 엔진이 있다.
– 매핑 룰을 수정하여 입력받은 URL을 적절한 컨트로러로 매핑시킬 수 있다.
– URL에 포함된 변수값들을 자동으로 파싱하여 해당 컨트롤러의 입력 파라미터
값으로 넘겨준다.
• Postback
– 서버와의 통신을 위해 더 이상 ASP.NET postback 모델을 사용하지 않는다.
– 모든 사용자 입력은 컨트롤러 클래스로 라우트된다.
– 따라서, ASP.NET view state와 ASP.NET page 관련 이벤트는 사용되지 않음.
12
1.1 MVC 프레임워크와 애플리케이션 구조
• ASP.NET MVC 애플리케이션 만들기
ASP.NET MVC Preview3을 설치하면 새로운 프로젝트 템플릿이 추가된다.
13
1.1 MVC 프레임워크와 애플리케이션 구조
• 웹 애플리케이션 MVC 프로젝트 구조
Controllers 폴더 밑에
새로운 컨트롤러 클래스를
만들되 “Controller”로
끝나는 이름으로 만든다.
새로운 Solution을 만들게 되면
MVC 애플리케이션 프로젝트와
Test 프로젝트가 생성된다.
각각의 컨트롤러의 이름과
동일한 이름을 갖는 폴더를
만든다.
URL 라우팅 규칙이
기술되어 있다.
14
1.1 MVC 프레임워크와 애플리케이션 구조
• 웹 애플리케이션 MVC 프로젝트 구조
새로운 Solution을 만들게 되면
MVC 애플리케이션 프로젝트와
Test 프로젝트가 생성된다.
Controllers 폴더 밑에
새로운 컨트롤러 클래스를
만들되 “Controller”로
끝나는 이름으로 만든다.
각각의 컨트롤러의 이름과
동일한 이름을 갖는 폴더를
만든다.
URL 라우팅 규칙이
기술되어 있다.
15
1.1 MVC 프레임워크와 애플리케이션 구조
• Global URL 라우팅 살펴 보기
– Global.aspx.cx 파일에 기본 라우팅 로직이 기술되어 있다.
– 라우팅 로직은 Application_Start 메서드가 호출될 때 초기화된다.
public class GlobalApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
// Note: Change the URL to "{controller}.mvc/{action}/{id}" to
// enable automatic support for IIS6 and for IIS7 classic mode.
// Handler to stop URL routing for Web resources.
routes.Add(
new Route(
"{resource}.axd/{*pathInfo}",
new StopRoutingHandler())
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
16
1.1 MVC 프레임워크와 애플리케이션 구조
• 라우팅
• Web.config파일에Url Routing을 위해 HttpModules 항목에 추가되어 있
다.
17
1.2 MVC 애플리케이션 실행 절차 이해하기
• 라우팅 관련 모듈
18
1.2 MVC 애플리케이션 실행 절차 이해하기
• 핸들러
– MVC 애플리케이션 내의 적절한 컨트롤러 클래스를 선택한다.
– 선택한 컨트롤러의 인스턴스를 얻는다.
– 컨트롤러의 Execute 메서드를 호출한다.
19
1.2 MVC 애플리케이션 실행 절차 이해하기
• 스테이지 별 MVC 웹 애플리케이션 실행 절차
스테이지
설명
애플리케이션에 처음으로
요청이 들어옴.
Global.asax 파일의 Route 객체가 RouteTable 객체에 추가됨.
라우팅 수행
UrlRoutingModule 모듈이 RouteTable 컬렉션 객체에서 요청에
맞는 Route 객체를 찾아 RequestContext(IHttpContext) 객체를
생성한다.
MVC reqeust 핸들러 생
성
MvcRouteHandler 객체는 MvcHandler 클래스의 인스턴스를 만들
어서 RequestContext 객체를 넘겨준다.
컨트롤러 생성
MvcHandler 객체가 RequestContext 인스턴스 정보를
IControllerFactory 객체에 넘겨서 적절한 Controller 인스턴스를
생성하도록 함.
컨트롤러 실행
MvcHandler 객체가 생성된 Controller 인스턴스의 Execute 메서드
를 호출함. (Command 패턴 참조)
Invoke action
대부분의 컨트롤러는 Controller 베이스 클래스로부터 상속받음.
Controller과 연결된 ControllerActionInvoker가 어느 액션을 수
행할 지 결정하여 해당 메서드를 호출한다.
20
1.3 컨트롤러와 컨트롤러 액션
• (Original) Front controller
– 외부로부터의 HTTP 요청을 처리하는 Handler 객체와
– 특정 행위를 수행하는 Command 객체로 구성됨. (Command 패턴 적용)
Microsoft
Enterprise Solution Patterns
ASP.NET MVC에서는
MvcHandler가 담당함
ASP.NET MVC에서는
Controller 클래스(abstract) 가
담당함
21
1.3 컨트롤러와 컨트롤러 액션
• 핸들러
22
1.3 컨트롤러와 컨트롤러 액션
• Sequence Diagram
23
1.3 컨트롤러와 컨트롤러 액션
• 컨트롤러
– Process incoming requests
– Handle user inputs and interactions
– Execute appropriate application logic
Command 패턴
24
1.3 컨트롤러와 컨트롤러 액션
• Ex)http://myCom.com/mySites/Home/About
Action Method
뷰 렌더링
25
1.3 컨트롤러와 컨트롤러 액션
• Action Result
– 모든 액션 메서드는 ActionResult 타입의 인스턴스를 리턴해야 한다.
View 메서드의 리턴 타입
RedirectToAction, RedirectToRoute
메서드의 리턴 타입
Redirect 메서드의 리턴 타입
Content 메서드의 리턴 타입
Json 메서드의 리턴 타입
액션 메서드가 널을 반환하는 경우
1.3 컨트롤러와 컨트롤러 액션
• 액션 메서드가 아닌 공용 메서드 만들기
– Controller 클래스 내의 모든 메서드는 자동적으로 Action method의 역할을
수행한다.
– 따라서, Action Method가 아닌 public method를 만들려면 ‘NonAction’ 속
성을 지정한다.
1.3 컨트롤러와 컨트롤러 액션
• 액션 메서드에서의 파라미터 처리
– Controller 클래스 내의 Request/Response 객체가
HttpRequest/HttpResponse 객체의 역할을 대신한다.
public void Detail()
{
int id = Convert.ToInt32(Request["id"]);
}
– Automatic action method parameter mapping
• /Products/Detail/3 ( /Products/Detail?id=3 )
public ResultAction Detail(int id)
{
ViewData["DetailInfo"] = id;
return View("Detail");
}
/{Controller}/{action}/{id}
– Optional Parameter
public ActionResult ShowArticles(DateTime? date)
{
if(!date.HasValue)
{
date = DateTime.Now;
}
// ...
}
Nullable type
1.4 뷰와 뷰 렌더링
Controller의 이름과 같은 폴더를 가진다.
29
1.4 뷰와 뷰 렌더링
• ViewResult 및 ViewPage 클래스
30
1.4 뷰와 뷰 렌더링
• ViewPage 생성 과정
31
1.4 뷰와 뷰 렌더링
• View
– 애플리케이션 로직이나 D/B접근 코드를 가져서는 안된다.
– 컨트롤러가 view 메서드를 호출하면서 넘겨주는 데이터 객체를 사용하여 화
면에 표시한다.
public ActionResult Categories()
{
List<Category> categories = northwind.GetCategories();
return View("Categories", categories);
}
렌더링할 뷰 이름.
액션 메서드 이름과 동일하기
때문에 생략 가능
32
1.4 뷰와 뷰 렌더링
• View로의 데이터 전달
– ViewDataDictionary 타입의 ViewData 이용하기 : key와 Value 활용
public SampleController : Controller {
public ActionResult Welcome() {
ViewData["FirstName"] = "Joe";
ViewData["LastName"] = "Healy";
return View();
}
}
– ViewPage<TModel> 이용하여 엄격한 타입의 데이터 전달하기
// 사용자가 만든 임의의 클래스
public class User
{
public string Name { get; set; }
public int Id { get; set; }
public int Age { get; set; }
....public string City { get; set; }
....public string State { get; set; }
}
public ActionResult User(int id)
{
User user = new User();
user = GetUserInfoFromDB(id);
return View(user);
}
33
1.4 뷰와 뷰 렌더링
• ViewPage에서 데이터 사용하기
– ViewData 속성 활용하기
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="About.aspx.cs"
Inherits="MvcApplication5.Views.Home.About" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>ViewData Property - Dictionary Based</title>
</head>
<body>
<div>
<%="About " + ViewData["CompanyName"]%>
</div>
</body>
</html>
– 엄격한 타입의 ViewData 활용하기 : ViewData.Model.프로퍼티이름
<form method="post" action="Home/Update">
Name: <%= Html.TextBox("name", ViewData.Model.Name) %><br />
Age: <%= Html.TextBox("age",
ViewData.Model.Age
%><br />
<input type="submit" value="Submit" />
</form>
34
2. ASP.NET Routing
http://server/application/Products/show/beverage
URL Routing
일반 웹 애플리케이션
URL Parser가 정의된 URL
패턴에 의해
Products,show 및
beverage 문자를 handler
에 요청값으로 넘겨준다.
/Products/show/bevera
ge 는 단지 애플리케이션
내의 파일 위치만을 나타
낼 뿐이다.
35
2.1 ASP.NET Routing .vs. URL Rewriting
URL 변경 여부
URL Rewriting
ASP.NET Routing
입력받은 요청에 대하
여 웹페이지로 전달되
기 전에 실제로 URL을
변경한다.
입력받은 요청을 처리
하면서 URL을 변경시
키지 않은채 파라미터
들을 추출한다.
Ex)
/Products/Widget 
/Products.aspx?id=4
URL 패턴
(route)
URL 패턴을 기반으로
하여 새로운 URL을 생
성하는 API가 제공되지
않는다.
한 곳에서만 URL 패턴
을 생성하거나 변경하
면 된다.
36
2.2 URL 라우트 정의하기
• {} 안에 URL 파라미터를 입력
• / 기호는 URL Parsing을 위한 구분자로 사용된다.
• {} 안에 들어가지 않은 문자는 모두 상수 처리한다.
Route 정의
매칭되는 URL의 예
{controller}/{action}/{id}
/Products/show/beverages
{table}/Details.aspx
/Products/Details.aspx
blog/{action}/{entry}
/blog/show/123
{reporttype}/{year}/{month}/{day}
/sales/2008/1/5
{locale}/{action}
/en-US/show
{language}-{country}/{action}
/en-US/show
37
2.2 URL 라우트 정의하기
• global.asax 파일
새로운 라우트 규칙 추가
Default 라우트 처리
38
2.3 다수 개의 URL 파라미터 처리
• 파라미터에 * 문자를 추가한다.
• ex) query/{queryName}/{*queryValue}
URL
/Category
Parameter values
action = "show" (default value)
categoryName = "food" (default value)
/Category/add
action = "add"
categoryName = "food" (default value)
/Category/add/beverages
action = "add"
categoryName= "beverages"
39
2.4 라우트에 제약 사항 걸기
• Costraints 만들기
– Regular expression을 사용하거나
– IRouteConstraint 인터페이스를 구현한 객체를 활용한다.
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route
(
"{locale}/{year}"
, new ReportRouteHandler()
)
{
Constraints = new RouteValueDictionary
{{"locale", "{a-z}{2}-{A-Z}{2}"},{year, @"\d{4}"}}
});
}
40
3. Action Filtering
• 사용자 행위에 대한 Action Method를 수행하기 전,후에 처리하
고 싶은 일이 있다면…?
–
–
–
–
사용자의 행위를 로그에 남긴다거나
리소스에 접근하고 하는 사용자에 대한 인증,권한 처리를 하고 싶다거나
처리 결과를 캐싱하고 싶다거나
로케일을 설정하고 싶다거나…
• Action Filter를 사용한다.
41
3.1 Action Filter의 구조
• ActionFilterAttribute
– 수행 단계에 따라 intercept할 수 있는 네 개의 필터가 있다.
42
3.1 Action Filter의 구조
• AOP와 유사한 Action Filter
Weaving 수행
CocntrollerActionInvoker 클래스
OnActionExecuting
해당 Controller의
Action Method 호출
Advice
OnActionExecuted
Action Filter
Core
Concerns
OnResultExecuting
ActionResult 인스턴스의
ExecuteResult 호출
OnResultExecuted
43
3.2 Action Filter 구현하기
• Trace 로그 남기는 Action Filter 만들기
– ActionFilterAttribute 로부터 상속받은 새로운 Attribute 클래스 생성
Action Method가 수행되기 직전에 호출된다.
public class LoggingFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Trace.Write("Starting: " +
filterContext.ActionMethod.Name);
base.OnActionExecuting(filterContext);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception != null)
filterContext.HttpContext.Trace.Write("Exception thrown");
base.OnActionExecuted(filterContext);
}
}
Action Method가 수행된 직후에 호출된다.
– ActionFilter마다 ControllerContext 클래스로부터 상속받은 객체들을 입력
파라미터로 받는다. (ActionExecutingContext,ActionExecutedContext,…)
44
3.2 Action Filter 구현하기
• Action Filter의 예외 처리
– ActionExecutingContext와 ResultExecutingContext 클래스에는 Cancel
속성이 있어 이 값에 따라 메서드 호출을 취소할 수도 있다.
– ActionExecutedContenxt와 ResultExecutedContext 클래스에는
Exception 속성과 ExceptionHandled 속성이 있어서 메서드 실행 후 발생할
수 있는 예외에 대한 처리를 수행할 수 있다.
45
3.3 Action Filter 적용하기
• 적용하고자 하는 Action Method에 Attribute 설정한다.
public class HomeController : Controller
{
static Boolean clicked = false;
[LoggingFilter]
public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";
if (clicked == true)
{
ViewData["Click"] = "You clicked this button.";
clicked = false;
}
return View();
}
[LoggingFilter]
public ActionResult About()
{
ViewData["Title"] = "About Page";
return View();
}
[LoggingFilter]
public ActionResult ClickMe()
{
clicked = true;
return RedirectToAction("Index");
}
}
46
참고 목록
• http://www.asp.net/mvc
• http://quickstarts.asp.net/3-5extensions/mvc/default.aspx
47