580 likes | 905 Views
ASP.NET MVC Framework. 장현희 ASP/ASP.NET MVP Senior Developer / MySpace Korea www.bullog.net. Part 1 : ASP.NET MVC Overview. MVC Pattern - Overview. Web Presentation Pattern 중 하나 Model, View, Controller 등의 컴포넌트로 구성 Model : Entity 클래스를 이용한 비즈니스 로직을 수행 View : 모델의 로직이 수행된 결과를 보여주는 역할
E N D
ASP.NET MVC Framework 장현희 ASP/ASP.NET MVP Senior Developer / MySpace Korea www.bullog.net
MVC Pattern - Overview • Web Presentation Pattern 중 하나 • Model, View, Controller 등의 컴포넌트로 구성 • Model: Entity 클래스를 이용한 비즈니스 로직을 수행 • View: 모델의 로직이 수행된 결과를 보여주는 역할 • Controller: 모델과 뷰 사이의 중재자 역할을 수행
ASP.NET vs. ASP.NET MVC Classic ASP.NET ASP.NET MVC Postback REST Request Model Code-Behind MVC Data Model
알고 계십니까? 예로부터 MVC 패턴에서 컨트롤러를 구현하는 두 가지 방법이 전해졌는데… ASP.NET은 원래 MVC 구조였다! PageController FrontController
MVC Pattern – Page Controller • Page Controller 패턴: 각각의 페이지를 처리하는 개별적인 컨트롤러를 구현 • ASP.NET 웹 폼 모델에 적용 • 빠르고 간편하게 개발 가능 • 코드 재사용이 용이 • Tightly Coupled • 기반 프레임워크에 대한 의존도 높음
MVC Pattern – Page Controller HTTP Request Model Controller View Controller View Controller View
MVC Pattern – Front Controller • 모든 HTTP 요청을 처리하는 하나의 컨트롤러를 구현 • ASP.NET MVC 프레임워크에 적용 • 모든 비즈니스 로직의 중앙 집중화 • 기반 프레임워크에 대한 의존도 낮음 • Loosely Coupled • 컨트롤러의 복잡도 증가 • 요청에 대한 병목
MVC Pattern – Front Controller HTTP Request Model Front Controller View View View
ASP.NET MVC 프레임워크의 특징 • HTTP 요청의 의미 변화 • 라우팅 엔진을 통해 SEO 및 REST에 적합한 형태의 URL을 지원 • URL은 리소스에 대한 요청이 아니라 컨트롤러의 특정 액션에 대한 요청으로 의미 변화 • 포스트 백은 없다 • ASP.NET의 최대 단점이었던 단일 서버 폼, ViewState 개념 삭제 • 페이지의 역할 변화 • 페이지와 사용자 정의 컨트롤은 뷰 템플릿으로 사용
ASP.NET MVC 프레임워크의 특징 • TDD의 손쉬운 적용 • 현존하는 모든 .NET 프레임워크용 단위 테스트 프레임워크 지원 • 컨트롤러의 액션 메서드 호출을 통해 ASP.NET 런타임을 통하지 않고도 손쉽게 애플리케이션 기능을 테스트할 수 있음 • ASP.NET과의 호환성 • 기존의 ASP.NET의 기능들을 모두 활용 가능
Front Controller 패턴 다시 보기 HTTP Request Routing Engine Model Front Controller View Controller Object Handler View Command View
URL Routing in ASP.NET MVC • HTTP 요청을 분석하여 해당 요청을 처리할 컨트롤러와 액션 메서드를 선택하는 중요한 모듈 • Front Controller 패턴에서 핸들러의 역할을 수행 • 지정된 페이지로의 Redirection을 수행하는 URL Rewriting과는 다른 개념 • 모델, 뷰, 컨트롤러와 완전히 독립적으로 동작. • ASP.NET에도 적용 예정
Routing Rule의 설정 • 기본적으로 Global.asax.cs파일에서 Application.Start이벤트에서 설정 • 키워드는 {keyword}와같이 표기 • controller와 action 키워드는 반드시 필요 • controller와 action 이외의 키워드는 해당 액션 메서드의 매개 변수로 전달됨 • RouteCollection.Add메서드나MapRoute확장 메서드를 사용 • 가장 먼저 등록된 라우팅 규칙부터 비교 • 가장 먼저 일치하는 규칙이 사용 됨.
Routing Rule의 설정 routes.Add( new Route( "{controller}/{action}/{id}", new MvcRouteHandler() ) { Defaults = new { controller = “Home”, action = "index" } } ); routes.MapRoute( "Default", “{controller}/{action}", new { controller = “Home", action = “Index" } );
Routing Rule의 사용 예 • 각 키워드에 할당된 값들은 RouteData클래스를 이용하여 접근할 수도 있음
Routing 규칙에서의 네임스페이스 사용 • 대형 프로젝트의 경우 MVC 애플리케이션 프로젝트에 모든 컨트롤러를 구현하기 어려움 • 이를 위해 별도의 어셈블리에 구현된 컨트롤러를 지정하기 위한 기능 • ControllerBuilder클래스의 DefaultNamespaces컬렉션에 컨트롤러 객체를 탐색할 네임스페이스를 지정 • 혹은 라우팅 규칙에 대해 개별적으로 지정 가능
Routing 규칙에서의 네임스페이스 사용 ControllerBuilder.Current.DefaultNamespaces.Add( “MyWebApps.Weblog.Controllers”);} vardataTokens = new RouteValueDictionary(); dataTokens.Add(“namespaces”, new HashSet<string>( new string[] { “MyWebApps.Weblog.Controllers”, “YourApps.Blog.Controllers” })); routes.Add( new Route(“{controller}/{action}/{id}”, new MvcRouteHandler()) { Defaults = new RouteValueDictionary( new { controller = “Home”, action = “index”, id = (string)null} ); DataTokens = dataTokens });
DEMO Routing Rules
Routing Constraint • 액션 메서드 실행에 대한 제약을 설정 • IRouteConstraint인터페이스를 구현한 모든 클래스는 라우팅 제약으로 사용 가능 • 현재 HttpMethodConstraint클래스가 제공되는 유일한 라우팅 제약 • HttpMethodConstraint클래스를 이용하면 특정 패턴의 URL 요청에 사용할 HTTP 메서드를 선택할 수 있음
HTTP 요청에 대한 제약 설정하기 • 액션 메서드를 GET 또는 POST 방식으로 요청한 경우에만 실행 • 제약에 위반되는 요청의 경우 HTTP 404 오류 반환 routes.MapRoute( "Default", “{controller}/{action}", new { controller = “Home", action = “Index" }, new{ httpMethod = new HttpMethodConstraint( “GET”, “POST” )} );
DEMO Routing Constraints
Model • 데이터와 관련된 로직을 수행하여 데이터를 조작하는 일련의 객체들 • Entity라고도 부르며 애플리케이션의 요구사항에 따라 적절한 Entity 클래스들을 구성할 필요가 있다. • 최근에는 다양한 ORM (Object-Relational Mapping) 도구들의 도움을 받을 수 있다. • LINQ to SQL • LINQ to Entity • NHibernate
DEMO Creating Model Component
Controller • 인바운드 요청을 처리하는 MVC 패턴의 핵심 컴포넌트 • ASP.NET MVC 프레임워크에서 컨트롤러는 요청 URL에 해당하는 액션 메서드를 통해 비즈니스 로직을 실행 • Model 컴포넌트와의 협업 • 실행 결과를 렌더링 할 적절한 뷰를 선택하는 역할
Controller • Controller 클래스를 상속하는 모든 클래스의 public 인스턴스메서드를 액션 메서드로 사용 • 액션 메서드로 사용하고 싶지 않은 메서드에는[NonAction] 특성 사용 public class Home { public ActionResult Index() { … } [NonAction] public string SayHello() { return “Hello, World!”; } }
Controller • [AcceptVerbs] 특성을 통해 HTTP 요청 메서드의 종류에 따라 재정의된 액션 메서드를 선택적으로 호출 가능 public ActionResult Index() { // GET 방식으로 호출될 경우 실행될 코드 } [AcceptVerbs(HttpVerbs.Post) { // POST 방식으로 호출될 경우 실행될 코드}
Controller 클래스의 동작 과정 • MvcRouteModule클래스가 요청 URL을 분석 • MvcHandler 클래스를 이용하여 해당 요청을 처리할 컨트롤러 객체를 생성하고 Execute 메서드를 호출 • Execute 메서드는ControllerActionInvoker클래스를 이용하여 컨트롤러의 액션 메서드를 호출 • 액션 메서드의 리턴 값에 따라 적당한 동작을 수행
Action Results • 모든 액션 메서드는ActionResult클래스를 상속하는 클래스를 리턴. • 리턴 값이 없는 액션 메서드에 한해 void 리턴 타입 사용 가능 • ActionResult는 추상 클래스이며 Controller 클래스의 메서드에 따라 다양한 결과를 리턴할 수 있음
Action Results • 액션 메서드는ActionResult클래스를 상속하는 6개의 클래스 중 하나를 리턴 • 각각의 ActionResult클래스는 Controller 클래스의 메서드 호출에 의해 리턴 됨 • 액션 메서드가null을 리턴하거나 리턴 타입이 void인 경우에는 묵시적으로 EmptyResult객체를 리턴 • Content메서드: ContentResult객체를 리턴. 지정된 문자열을 응답 스트림에 출력 • Json메서드: JsonResult객체를 리턴. 지정된 객체를 JSON 문자열로 변환하여 응답 스트림에 출력
Action Results • PartialView메서드: 지정된 뷰를 현재 뷰에렌더링하는메서드. PartialViewResult객체를 리턴 • Redirect메서드: 지정된 URL로 이동하는 메서드. RedirectResult객체를 리턴 • RedirectToAction메서드: RedirectToActionResult객체를 리턴. 지정된 액션 메서드를 호출 • RedirectToRoute메서드: RedirectToRouteResult객체를 리턴. 지정된 경로로 라우팅 됨 • View메서드: 지정된뷰를렌더링. 뷰를렌더링 하는 유일한 메서드
컨트롤러에서 뷰로의 데이터 전달 • 컨트롤러와 뷰 사이의 데이터 교환은 ViewDataDictionary클래스를 통해 이루어짐 • ViewDataDictionary클래스는 Controller 및 ViewPage클래스에 ViewData속성을 통해 접근 가능 • Dictionary<string, object> 타입을 상속하므로 모든 종류의 객체를 담을 수 있음
컨트롤러에서 뷰로의 데이터 전달 public class Home { public ActionResult Index() { ViewData[“TotalItems”] = GetTotalItems(); ViewData[“DataContainer”] = GetLists(); } } protected override void OnLoad(EventArgs e) { this.repeater1.DataSource = ViewData[“DataContainer”]; this.totalItemsLabel.Text = ViewData[“TotalItems”].ToString();}
컨트롤러에서 뷰로의 데이터 전달 • Dictionary 기반이므로 모든 타입의 데이터를 컨트롤러에서 뷰로 전달 가능 • 그러나 Object 타입이므로 형 변환 및 Boxing/Unboxing으로인한 성능 문제 발생 가능 • ViewPage<T> 클래스를 이용하여 강력한 타입의 뷰 데이터 교환 가능
DEMO Implement Controllers
View • Model과 Controller의 비즈니스 로직 실행 결과를 보여주기 위한 컴포넌트 • ASP.NET MVC 프레임워크에서는 ASPX및 ASCX 파일을 뷰 템플릿으로 사용 • 모든 ASPX 페이지에 대한 직접적인 요청은 HTTP Forbidden 핸들러가 처리 • 페이지 라이프 사이클 이벤트들은 여전히 사용 가능 • 서버 폼이 필요 없는 서버 컨트롤들 역시 여전히 사용 가능
View • Controller.View메서드에 지정된 뷰의 이름과 동일한 이름의 ASPX 혹은 ASCX 파일을 생성해야 함 • 뷰가렌더링 될 때 뷰 파일의 탐색 순서 • ~/Views/컨트롤러/뷰.aspx • ~/Views/컨트롤러/뷰.ascx • ~/Shared/뷰.aspx • ~/Shared/뷰.ascx
ViewPage클래스 • 모든 뷰 페이지들은 ViewPage클래스 혹은 ViewPage<T> 클래스를 상속해야 함 • ViewPage<T> 클래스를 이용할 경우 보다 강력한 타입을 가진 뷰 데이터를 사용할 수 있음 • AjaxHelper, HtmlHelper등의 Helper 클래스들에 대한 액세스를 제공 • ViewContext속성을 통해 현재 실행 중인 요청 및 컨트롤러 액션에 대한 액세스 가능 • 뷰 파일이 ASCX인 경우에는 ViewUserControl혹은 ViewUserControl<T> 클래스를 사용
DEMO Handling View Data
HtmlHelper클래스 • 뷰 페이지에서 UI 요소들을 생성할 때 활용할 수 있는 다양한 메서드를 제공하는 Helper 클래스 • 실제로는 대부분의 메서드들이 확장 메서드로 구현되어 있음 • FormExtensions클래스 • InputExtensions클래스 • LinkExtensions클래스 • RenderPartialExtensions클래스 • SelectExtensions클래스 • TextAreaExtensions클래스 • ValidationExtensions클래스
HtmlHelper클래스 • FormExtensions클래스 • 페이지에 <FORM> 태그를 렌더링 하기 위한 BeginForm / EndForm메서드 쌍을 제공 • 다음의 두 가지 방식으로 사용 가능 <% using (Html.BeginForm()) { %> <% = Html.TextBox(“textField1”) %> <% = Html.SubmitButton(“button1”) %> <% } %> <% Html.BeginForm(); %> <% = Html.TextBox(“textField1”) %> <% = Html.SubmitButton(“button1”) %> <% Html.EndForm(); %>
HtmlHelper클래스 • InputExtensions클래스 • 입력용 요소를 렌더링하기 위한 메서드들을 제공하는 클래스 • CheckBox메서드 • Hidden 메서드 • Password 메서드 • RadioButton메서드 • TextBox메서드
HtmlHelper클래스 • LinkExtensions클래스 • 하이퍼링크를 렌더링하기 위한 메서드들을 제공하는 클래스 • ActionLink메서드: 컨트롤러의 액션 메서드를 호출하는 링크를 생성 • GenerateLink메서드: ActionLink메서드와 유사한 역할을 수행. ActionLink메서드는 내부적으로 GenerateLink메서드를 사용 • RouteLink메서드: 지정된 라우팅 규칙에 해당하는 URL을 생성하는 메서드. 역시 내부적으로 GenerateLink메서드를 사용
HtmlHelper클래스 • RenderPartialExtensions클래스 • RenderPartial메서드: 지정된 뷰를 현재 뷰에렌더링하는메서드 • SelectExtensions클래스 • DropDownList메서드: 드롭다운 목록을 렌더링하는메서드 • ListBox메서드: 리스트 상자를 렌더링하는메서드 • TextAreaExtensions클래스 • TextArea메서드: <TEXTAREA> 태그를 렌더링하는메서드
HtmlHelper클래스 • ValidationExtensions클래스 • ValiationMessage메서드: 유효성 검사 실패 시 사용자에게 보여줄 메시지를 렌더링하는메서드 • ValidationSummary메서드: 페이지에서 발생한 모든 유효성 검사 실패 오류 메시지를 한 곳에 모아 렌더링하는메서드
DEMO Building UI elements using HtmlHelper class
AjaxHelper클래스 • AJAX 요청을 지원하기 위한 클래스 • ActionLink메서드 • BeginForm메서드 • RouteLink메서드 • 제공되는 메서드의 기능은 HtmlHelper클래스의 메서드와 동일하지만 요청을 AJAX로 처리 • Scripts 폴더의 MicrosoftAjax.js와 MicrosoftMvcAjax.js 두 개의 스크립트를 페이지에 추가해 주어야 함