'ASP.NET MVC'에 해당되는 글 9건

  1. 2008.12.23 ASP.NET MVC Tutorial #11
  2. 2008.12.08 ASP.NET MVC Tutorial #10 1
  3. 2008.12.05 ASP.NET MVC Tutorial #09
  4. 2008.12.02 ASP.NET MVC Tutorial #06
  5. 2008.12.01 ASP.NET MVC Tutorial #05

  • Creating a Tasklist Application with ASP.NET MVC
  • Understanding Models, Views, and Controllers
  • Understanding Controllers, Controller Actions, and Action Results
  • Understanding Views, View Data, and HTML Helpers
  • An Introduction to URL Routing
  • Preventing JavaScript Injection Attacks
  • Creating Unit Tests for ASP.NET MVC Applications
  • Using ASP.NET MVC with Different Versions of IIS
  • Creating Custom HTML Helpers
  • Creating Model Classes with LINQ to SQL
  • Displaying a Table of Database Data
  • Creating Page Layouts with View Master Pages
  • Passing Data to View Master Pages
  • Understanding Action Filters

    전 튜토리얼과 비슷한 내용이지만.
    읽어보세요 :)


    Displaying a Table of Database Data

     

    이 튜토리얼에서, 데이터베이스 레코드를 표현하는 두 가지 메소드를 설명할 것입니다. HTML 테이블에서 데이터베이스 레코드의 집합을 두 가지 형식으로 설명할 것입니다. 첫 번째로, view에서 바로 데이터베이스 레코드를 접근하는 것과, 다음으로

     

    Create the Model Classes

     

    Movies 데이터베이스 테이블의 레코드들을 화면에 나타낼 것입니다. Movies 데이터베이스 테이블은 다음과 같은 칼럼으로 구성되어 있습니다.

     

    Column Name

    Data Type

    Allow Nulls

    Id

    Int

    False

    Title

    Nvarchar(200)

    False

    Director

    NVarchar(50)

    False

    DateReleased

    DateTime

    False

     

    Movies 데이터베이스 테이블을 나타내기 위해, 데이터베이스 액세스 기술로 LINQ to SQL을 사용할 것입니다. , LINQ to SQL을 사용하여 MVC model을 구현할 것입니다.

     

    LINQ to SQL 클래스를 만드는 가장 빠른 방법은 Visual Studio Object Relational Designer을 사용하는 것입니다. Model 폴더에서 우 클릭을 한 후, LINQ to SQL 클래스 템플릿을 추가하세요.

     

     

    Movie LINQ to SQL 클래스를 만들고 나면, Object Relational Designer가 나타날 것입니다. 서버 탐색기로부터 데이터베이스 테이블을 Object Relational Designer 로 드래그하세요.

     


     
    기본적으로, Object Relational Designer은 데이터베이스 테이블 이름을 단수형으로 단수 형으로 만듭니다. 예를 들어, Customers 라는 데이터베이스 테이블이 있을 때, 드래그 하여 추가하면 Object Relational Designer Customer라 이름을 만들 것입니다.

     

    Object Relational Designer에서 테이블 이름 변경은 가능합니다.

     

    Using LINQ to SQL in a Controller Action

     

    LINQ to SQL 클래스를 만든 것은, 데이터베이스로부터 데이터를 가져올 클래스가 생겼다는 것입니다. 아래의 코드의 controller 클래스는 Movies 데이터베이스 테이블로부터 movie 레코드를 가져오기 위해 LINQ to SQL 클래스를 사용합니다.

     

    using System.Linq;

    using System.Web.Mvc;

    using MvcApplication1.Models;

     

    namespace MvcApplication1.Controllers

    {

             [HandleError]

             public class HomeController : Controller

             {

                  public ActionResult Index()

                  {

                       var dataContext = new MovieDataContext();

                       var movies = from m in dataContext.Movies

                            select m;

                       return View(movies);

                  }

             }

    }

     

    Index() action은 데이터베이스 테이블로부터 movies을 가져오기 위해 LINQ to SQL MovieDataContext 클래스를 사용합니다. Movies 목록은 ViewData.Model 속성의 값으로 Index view로 전달됩니다.

     

    Formatting within a View

     

    가장 단순하지만, 최고의 방법은 아닌, 데이터베이스 레코드 집합을 형식화 하는 메소드(method of formatting) view에서 바로 데이터를 보여줍니다. 예를 들어, 아래 코드의 Index view HTML 테이블 내에서 movie 데이터베이스 레코드를 렌더링 합니다.

     

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"

     CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>

    <%@ Import Namespace="MvcApplication1.Models" %>

    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

     

    <table>

    <tr>

         <th>Id</th><th>Title</th><th>Release Date</th>

    </tr>

    <% foreach (Movie m in (IEnumerable)ViewData.Model)

    { %>

    <tr>

         <td><%= m.Id %></td>

         <td><%= Html.Encode(m.Title) %></td>

         <td><%= m.DateReleased %></td>

    </tr>

    <% } %>

    </table>

     

    </asp:Content>

     

    View은 각각의 movie 레코드를 반복하는 foreach 루프 구문으로 구성되어 있습니다. 각각의 movie 속성 값은 테이블의 각 셀마다 표시됩니다. 테이블 행은 HTML <tr> 태그로 만들고 테이블 셀은 HTML <td> 태그로 만듭니다.

     

    Html.Encode() helper 메소드는 값이 표시되기 전에 각 속성 값을 인코딩 합니다. 사용자 입력 값을 받고, 그 입력 값을 가져와 화면에 표시할 때마다, 자바스크립트 인젝션 공격을 막는 것은 매우 중요합니다.

     

    어플리케이션을 실행 시키면, 아래와 같이 Index view가 렌더링 되어 출력됩니다.

     


     

    그런데, HTML 테이블 형식이 존재하지 않습니다. 그래서 CSS을 사용하여 HTML 테이블의 외관을 향상 시킬 필요가 있습니다.

     

    마스터 페이지의 <head>태그 사이에 다음과 같은 코드를 추가시킵니다.

     

    <style type="text/css">

    table

    {

         border-collapse:collapse;

    }

     

    table td, table th

    {

         border: solid 1px black;

         padding:10px;

    }

    </style>

     

    마스터 페이지에 CSS 코드를 추가한 후, Index view은 다음과 같이 페이지가 보여질 것입니다.


     

     

    Formatting within a Partial

     

    view에서 모든 형식 코드가 동작하기도 하지만, 템플릿으로 특정 부분만 사용할 수도 있습니다. 예를 들어, 다음 코드는 특정 movie 데이터베이스 레코드를 위한 형식입니다. (사용자 정의 컨트롤)

     

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MovieTemplate.ascx.cs"

     Inherits="MvcApplication1.Views.Movies.MovieTemplate" %>

    <tr>

         <td> <%=ViewData.Model.Id%></td>

         <td> <%=Html.Encode(ViewData.Model.Title)%></td>

         <td> <%=ViewData.Model.DateReleased.ToString("D")%></td>

    </tr>

     

     

    위 코드에서 템플릿은 HTML 테이블의 행으로서 각각 movie 레코드의 형태를 갖추고 있습니다. ViewData.Model 속성은 특정 부분 내에서, 모든 데이터베이스 레코드가 아닌 하나의 데이터베이스 레코드를 나타냅니다.

     

    Movie 클래스의 개체에서 ViewData.Model 속성을 캐스팅하기 위해, 특정 부분을 위한 코드 비하인드 클래스를 만들어야 합니다. 아래 코드에서, 코드 비하인드 클래스는 타입 파라메터로 Movie을 가지고 있는 제네릭 클래스를 상속 받는 MovieTemplate 클래스를 정의하고 있습니다.

     

    using MvcApplication1.Models;

    namespace MvcApplication1.Views.Movies

    {

         public partial class MovieTemplate : System.Web.Mvc.ViewUserControl<Movie>

         {

         }

    }

     

    MovieTemplate 클래스는 ViewUserControl<movie> 클래스를 상속받습니다. MovieTemplate 클래스가 이 클래스를 상속받기 때문에, ViewData.Model 속성은 자동적으로 Movie을 캐스팅합니다.

     

    아래 코드에서 Index viewview에서 MovieTemplate을 어떻게 사용하는지 설명하고 있습니다. Html.RenderPartial() 메소드는 MovieTemplate을 렌더링 하기 위해 사용합니다.

     

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"

     CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Movies.Index" %>

    <%@ Import Namespace="MvcApplication1.Models" %>

    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

     

    <table>

    <tr>

         <th>Id</th><th>Title</th><th>Release Date</th>

    </tr>

         <% foreach (Movie m in (IEnumerable)ViewData.Model)

         {

              Html.RenderPartial("MovieTemplate", m);  

         } %>

    </table>

     

    </asp:Content>

     

    위 코드에서, Html.RenderPartial() 메소드는 각 Movie 레코드를 나타내기 위해 MovieTemplate을 렌더링 하는데 사용됩니다. 두 파라메터는 RenderPartial() 메소드로 전달합니다. 첫 번째 파라메터는 렌더링 할 템플릿의 이름입니다. 기본적으로, 템플릿은 Views\ControllerName 폴더 또는 Vies\Shared 폴더에 위치되어야 합니다.

     

    두 번째 파라메터는 템플릿에 전달되는 view data 입니다. 템플릿에서, ViewData.Model 속성은 특정 Movie 레코드를 나타냅니다.

     

    하나 중요한 것으로, Html.RenderPartial() 메소드는 다른 Helper 메소드와는 달리, string을 리턴 하지 않는다는 것입니다. 이것은 아래처럼 Renderpartial() 메소드를 호출하지 못한다는 것입니다.

     

    <%= Html.RenderPartial("MovieTemplate", m) %>

     

    아래와 같이 사용해야 합니다.

     

    <% Html.RenderPartial("MovieTemplate", m); %>

     

    RenderPartial() 메소드는 어떤 일, 행동을 의미하는 것이지, 그것을 표현하는 것은 아니다.


  • Posted by glycerine
    ,
  • Creating a Tasklist Application with ASP.NET MVC
  • Understanding Models, Views, and Controllers
  • Understanding Controllers, Controller Actions, and Action Results
  • Understanding Views, View Data, and HTML Helpers
  • An Introduction to URL Routing
  • Preventing JavaScript Injection Attacks
  • Creating Unit Tests for ASP.NET MVC Applications
  • Using ASP.NET MVC with Different Versions of IIS
  • Creating Custom HTML Helpers
  • Creating Model Classes with LINQ to SQL
  • Displaying a Table of Database Data
  • Creating Page Layouts with View Master Pages
  • Passing Data to View Master Pages
  • Understanding Action Filters
  • LINQ 부분 정리해서 포스팅한다는게 계속 미뤄지네요.
    지금 튜토리얼은 LINQ에 대한 지식이 약간 필요합니다.

    후반부에 패턴에 대한 이야기가 나오는데. 핵심은 이거네요.
    가져올 데이터베이스 로직을 각 Controller 클래스가 아닌
    데이터베이스 로직에 해당하는
    인터페이스와 클래스를 따로 작성하여 관리하는 효율적인 방법을 제시하였네요.
    아마 많이 쓰는 부분이라 생각드네요.

    Creating Model Classes with LINQ to SQL

     

    이 튜토리얼의 목적은 ASP.NET MVC 어플리케이션에서 model 클래스를 만드는 하나의 메소드를 설명하는 것입니다. 이 튜토리얼에서, LINQ to SQL을 이용하여 어떻게 model 클래스를 빌드하고 데이터베이스에 연결하는지 설명할 것입니다.

     

    예제로, 기본 Movie 데이터베이스 어플리케이션을 만들 것 입니다. 모든 데이터들은 controller actions에 바로 연결할 것입니다.

     

    그리고, Repository 패턴을 어떻게 사용하는지 배울 것입니다. Repository 패턴은 약간의 추가 작업을 필요로 합니다. 그러나, 이 패턴을 사용함으로써 유연한 어플리케이션을 만들 수 있고, 쉽게 테스트 할 수 있습니다.

     

    What is a Model Class?

     

    MVC model MVC view 또는 controller에 포함되지 않은 모든 어플리케이션 로직을 가지고 있습니다. 특히, MVC model은 비즈니스 로직과 데이터 액세스 로직을 가지고 있습니다.

     

    사용자는 데이터 액세스 로직 구현을 위한 다양한 기술들을 적용할 수 있습니다. 예를 들어, Microsoft Entity Framework, NHibernate, Subsonic, 또는 ADO.NET classes 등을 사용함으로써 데이터 액세스 클래스를 만들 수 있습니다.

     

    이 튜토리얼에서는 데이터베이스에 쿼리와 업데이트하기 위해 LINQ to SQL을 사용할 것입니다. LINQ to SQL SQL 데이터베이스와 상호작용하는 간단한 메소드를 제공합니다. 그러나, ASP.NET MVC 프레임워크는 LINQ to SQL에만 한정적 인 것이 아니라, 다른 데이터 액세스 기술과도 잘 융합됩니다.

     

    Creating a Movie Database

     

    이 튜토리얼에서 model 클래스를 어떻게 구성하는 설명하기 위해 간단한 Movie 데이터베이스 어플리케이션을 만들 것입니다. 첫 단계로, 새로운 데이터 베이스를 만듭니다. (아래 표 참고)

     

    Column Name

    Data Type

    Allow Nulls

    Id

    Int

    False

    Title

    Nvarchar(200)

    False

    Director

    Nvarchar(50)

    False

     

     

    Creating LINQ to SQL Classes

     

    MVC model은 데이터베이스 테이블을 의미하는 LINQ to SQL 클래스를 가지고 있어야 합니다. 이 클래스를 만드는 가장 쉬운 방법은 LINQ to SQL 템플릿을 추가 하는 것입니다.

    (Model 폴더 우 클릭 추가 – Linq to sql 템플릿)

     

    LINQ to SQL 클래스를 생성하면, Object Relational Designer 가 나타날 것입니다. 서버 탐색기에서 해당하는 데이터베이스를 Object Relational Designer로 드래그 할 수 있습니다. (아래 그림)

     

     



    기본적으로, Object Relational Designer은 사용자가 드래그 한 데이터베이스 테이블과 같은 이름의 클래스를 만듭니다.

    (저장 필수)


    Using LINQ to SQL in a Controller Action

     

    이 클래스를 만듦으로써, 데이터베이스와 통신할 수 있습니다. 이제, controller action에서 LINQ to SQL 클래스를 어떻게 사용하는지 설명할 것입니다. 우리는 MVC view에서 Movie 데이터베이스 테이블로부터 영화 목록을 보여줄 것입니다.

     

    처음에, HomeController 클래스를 아래 코드와 같이 수정해야 합니다.

     

    주의! Using 네임스페이스.Models

     

    using System.Linq;

    using System.Web.Mvc;

    using MvcApplication1.Models;

     

    namespace MvcApplication1.Controllers

    {

         [HandleError]

         public class HomeController : Controller

         {

              public ActionResult Index()

              {

                   var dataContext = new MovieDataContext();

                   var movies = from m in dataContext.Movies

                        select m;

                   return View(movies);

              }

         }

    }

     

    위 코드에서 Index() action MoviesDB 데이터베이스를 나타내는 LINQ to SQL DataContext 클래스(the MovieDataContext)를 사용합니다. MovieDataContext 클래스는 Visual Studio Object Reletional Designer에 의해 생성되었습니다.

     

    LINQ 쿼리는 데이터베이스 테이블에서 모든 movie와 통신하는 DataContext에 맞게 동작합니다. Movie 목록은 movies 라는 지역 변수에 명명되었습니다. 마지막으로, movie 목록은, view data view에 전달됩니다.

     

    Movie을 보기 위해, Index view 역시 아래 코드로 수정해야 합니다.

     

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"

       CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>

    <%@ Import Namespace="MvcApplication1.Models" %>

    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

         <ul>

              <% foreach (Movie m in (IEnumerable)ViewData.Model)

              { %>

                   <li> <%= m.Title %> </li>

              <% } %>

         </ul>

    </asp:Content>

     

    View의 상단에 <%@ import namespace %> 을 포함하는 것을 주의하세요. Model 클래스를 작업하기 위해 이 네임스페이스가 필요합니다.

     

    위 코드에서 view ViewData.Model 속성에 의해 표현될 아이템을 반복하여 보여줄 foreach 루프를 가지고 있습니다. 각 무비의 타이틀 속성이 보여질 것입니다.

     

    ViewData.Model 속성 값은 IEnumerable 로 캐스팅하는 것을 주의하세요. ViewData.Model의 콘텐트를 loop 로 사용하기 위해 필수적입니다.

     

    HomeController 클래스와 Index view을 수정하고 어플리케이션을 실행 시키면, 데이터베이스에 값이 없기 때문에 빈 화면이 나타날 것입니다.

     

    데이터베이스에 값을 넣고 실행시켜 보세요.

     

    Using the Repository Pattern

     

    지금까지, controller action에서 바로 LINQ to SQL 클래스를 사용했습니다. 다시 말해 MovieDataContext 클래스에서 Index() controller action으로 바로 데이터를 넘겼습니다. 간단한 어플리케이션에서는 문제가 없지만, 복잡한 어플리케이션을 만듦에 있어서 controller 클래스 내의 LINQ to SQL 로 바로 작업하는 것은 문제가 생길 수 있습니다.

     

    Controller 클래스에서 LINQ to SQL을 사용하는 것은 차후 데이터 액세스 기술을 변동할 때 어렵습니다. 예를 들어, Microsoft Entity Framework 로 데이터 액세스 기술을 바꾼다고 할 때, 데이터베이스와 연결된 모든 controller을 다시 작성해야 하는 일이 생깁니다.

     

    앞으로의 변화에 더 유연한 MVC 어플리케이션을 만들기 위해서, Repository 패턴을 생각해 볼 수 있습니다. Repository 패턴을 사용할 때, 데이터베이스 액세스 로직을 구성하는 분할된 repository 클래스를 만듭니다.

     

    Repository 클래스에서 사용되는 모든 메소드를 나타내는 인터페이스를 만들어야 합니다. controller에서는 repository가 아닌 인터페이스에 맞는 코드를 작성해야 합니다. 이와 같은 방식으로, repository을 구현할 수 있습니다.

     

    아래 코드에서 IMovieRepository 인터페이스는 IList<Movie>을 리턴하는 하나의 ListAll() 메소드를 가지고 있습니다.

     

    using System.Collections.Generic;

    namespace MvcApplication1.Models

    {

             public interface IMovieRepository

             {

                  IList<Movie> ListAll();

             }

    }

     

    아래 코드에서 repository 클래스는 IMovieRepository 인터페이스를 구현하였습니다. IMovieRepository 인터페이스에 정의된 ListAll 메소드가 구현된 것을 주의하세요.

     

    using System.Collections.Generic;

    using System.Linq;

     

    namespace MvcApplication1.Models

    {

             public class MovieRepository : IMovieRepository

             {

                  private MovieDataContext _dataContext;

     

                  public MovieRepository()

                  {

                        _dataContext = new MovieDataContext();

                  }

     

                  #region IMovieRepository Members

     

                  public IList<Movie> ListAll()

                  {

                       var movies = from m in _dataContext.Movies

                            select m;

                       return movies.ToList();

                  }

     

                  #endregion

             }

    }

     

    마지막으로, 아래 코드의 MoviesController 클래스는 Repository 패턴을 사용하고 있습니다.

     

     

    using System.Web.Mvc;

    using MvcApplication1.Models;

     

    namespace MvcApplication1.Controllers

    {

             public class MoviesController : Controller

             {

                  private IMovieRepository _repository;

     

                  public MoviesController() : this(new MovieRepository())

                  {

                  }

     

                  public MoviesController(IMovieRepository repository)

                  {

                       _repository = repository;

                  }

     

                  public ActionResult Index()

                  {

                       return View(_repository.ListAll());

                  }

             }

    }

     

    위 코드에서 MoviesController은 두 가지 생성자를 가지고 있는 것을 주의해야 합니다. 첫 번째 생성자는, 파라메터가 없는 생성자로서, 어플리케이션이 동작할 때, 호출됩니다. 이 생성자는 MovieRepository 클래스의 개체를 만들고 그것을 두 번째 생성자로 전달합니다.

     

    두 번째 생성자는 IMovieRepository 파라메터 하나를 매개변수로 가지고 있습니다. 이 생성자는 _repository 라는 클래스 단위 필드에 파라메터 값으로 지정합니다.

     

    MoviesController 클래스는 Dependency Injection pattern 이라 불리는 디자인 패턴입니다. 특히, Contructor Dependency Injection 이라 불리는 것을 사용하는 것입니다. 다음 링크에서 이 패턴에 관한 자세한 글을 확인 할 수 있습니다.

     

    http://martinfowler.com/articles/injection.html

     

    MoviesController 클래스의 모든 코드는 실제 MovieRepository 클래스가 아니라 IMovieRepository 인터페이스와 작용합니다. 코드는 구체적인 인터페이스의 구현이 아니라 추상인터페이스 구현입니다.

     

    데이터 액세스 기술을 수정하기를 원한다면 다른 기술을 사용하는 클래스 내의 IMovieRepository 인터페이스를 구현함으로써 적용할 수 있습니다. 예를 들어, EntityFrameworkMovieRepository 클래스나 SubSonicMovieRepository 클래스를 만들 수 있습니다. Controller 클래스가 interface에 맞게 구현하였기에, 새로 구현된 IMovieRepositorycontroller 클래스에 전달하여 계속 작업할 수 있습니다.

    Posted by glycerine
    ,

  • Creating a Tasklist Application with ASP.NET MVC
  • Understanding Models, Views, and Controllers
  • Understanding Controllers, Controller Actions, and Action Results
  • Understanding Views, View Data, and HTML Helpers
  • An Introduction to URL Routing
  • Preventing JavaScript Injection Attacks
  • Creating Unit Tests for ASP.NET MVC Applications
  • Using ASP.NET MVC with Different Versions of IIS
  • Creating Custom HTML Helpers
  • Creating Model Classes with LINQ to SQL
  • Displaying a Table of Database Data
  • Creating Page Layouts with View Master Pages
  • Passing Data to View Master Pages
  • Understanding Action Filters


    Unit Test는 한글 VS 적용이 안되는 점,
    IIS 쪽 부분은 다른 블로그 내용이 더 좋은 것 같아 다른 글을 다뤄 볼까 해요.
    아직은 어설픈 해석만 하고 있지만 튜토리얼 정리가 끝나고 미니 프로젝트를 다뤄볼까 합니다 :)


    Creating Custom HTML Helpers

     

    이 튜토리얼의 목적은 MVC views에서 사용할 수 있는 사용자 정의 HTML Helpers을 어떻게 만드는 지 설명하는 것입니다. HTML Helpers의 장점으로, HTML 태그의 코드 양을 감소할 수 있습니다.

     

    이 튜토리얼의 첫 파트에서, ASP.NET MVC 프레임워크에 내장된 HTML Helpers에 대해 알아 볼 것이고, 다음으로 사용자 정의 HTML Helpers을 만드는 두 가지 메소드를 설명할 것입니다.

     

    Understanding HTML Helpers

     

    HTML Helper은 단순한 string을 리턴 하는 메소드 입니다. String은 사용자가 원하는 여러 타입의 콘텐트를 나타냅니다. 예를 들어, HTML <input> <img> 태그와 같이 표준 HTML 태그를 렌더링 할 때 HTML Helpers을 사용할 수 있습니다. , 데이터베이스 데이터로부터 HTML table을 만드는 경우와 같이 복잡한 콘텐트를 렌더링 하기 위해서도 사용할 수 있습니다.

     

    ASP.NET MVC 프레임워크는 다음 표준 HTML Helpers을 포함하고 있습니다.

     

    l  Html.ActionLink()

    l  Html.BeginForm()

    l  Html.CheckBox()

    l  Html.DropDownList()

    l  Html.EndForm()

    l  Html.Hidden()

    l  Html.ListBox()

    l  Html.Password()

    l  Html.RadioButton()

    l  Html.TextArea()

    l  Html.TextBox()

     

    예를 들어, 아래의 폼을 생각해 봅시다. 이 폼은 두 개의 표준 HTML Helpers로 렌더링 되었습니다.



     

    <%@ Page Language="C#" AutoEventWireup="true"

    CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index"%>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns= "http://www.w3.org/1999/xhtml ">

    <head id="Head1" runat="server">

         <title>Index</title>

    </head>

    <body>

          <div>

              <% using (Html.BeginForm())

              { %>

                   <label for="firstName">First Name:</label>

                   <br />

                   <%= Html.TextBox("firstName")%>

                   <br /><br />

                   <label for="lastName">Last Name:</label>

                   <br />

                   <%= Html.TextBox("lastName")%>

                   <br /><br />

                   <input type="submit" value="Register" />   

              <% } %>

         1     </div>

    </body>

    </html>

     

    Html.BeginForm() Helper 메소드는 HTML <form> 태그의 시작과 끝을 만드는데 사용된다. Html.BeginForm() 메소드는 using 문안에서 호출 되어 진다는 것을 명심해야 합니다. Using 문은 <form> 태그가 using 블록의 끝에서 닫히게 되는 것을 보장해줍니다.

     

    Using 블록을 만드는 것 대신에, <form> 태그를 닫기 위해 Html.EndForm() Helper 메소드를 호출 할 수도 있습니다. 사용자가 편한 방법으로 <form> 태그를 닫고 여는 방법을 선택할 수 있습니다.

     

    위 코드에서 Html.TextBox() Helper 메소드는 Html <input> 태그를 렌더링 합니다. 웹 브라우저에서 소스 보기를 한다면 아래와 같은 코드를 볼 것입니다.

     

    중요! Html.TextBox() Html Helper <$ $> 태그가 아니라 <$= $> 태그 내에서 렌더링 됩니다. ‘=’ 기호가 포함되어 있지 않다면, 브라우저에서 렌더링 되지 않을 것입니다.

     

    <%@ Page Language="C#" AutoEventWireup="false" CodeBehind="Index.aspx.cs"

     Inherits="MvcApplication1.Index" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">

    <head>

         <title>Index</title>

    </head>

    <body>

         <div>

              <form action="http://localhost:33102/" method="post">

                   <label for="firstName">First Name:</label>

                   <br />

                   <input id="firstName" name="firstName" type="text" value="" />

                   <br /><br />

                   <label for="lastName">Last Name:</label>

                   <br />

                   <input id="lastName" name="lastName" type="text" value="" />

                   <br /><br />

                   <input id="btnRegister" name="btnRegister" type="submit" value="Register" />

              </form>

         </div>

    </body>

    </html>

     

    ASP.NET MVC 프레임워크의 helper은 소규모 이기에, 대부분 사용자들은 사용자 정의 HTML Helpers 로 확장하기를 원할 것입니다.

     

    Creating HTML Helpers with Static Methods

     

    새로운 HTML Helper을 만드는 가장 쉬운 방법은 문자를 리턴 하는 static 메소드를 만드는 것입니다. 예를 들어, HTML <label> 태그를 렌더링 하는 새로운 HTML Helper을 만든다고 생각해 봅시다. 사용자는 <label>을 렌더링 하기 위한 아래 코드의 클래스를 사용할 수 있습니다.

     

    using System;

    namespace MvcApplication1.Helpers

    {

              public class LabelHelper

              {

                   public static string Label(string target, string text)

                   {

                        return String.Format("<label for='{0}'>{1}</label>", target, text);

                   }

              }

    }

     

     

    위 코드에서 클래스에 관해 특별한 것이 없습니다. Label() 메소드는 단지 문자를 리턴 합니다.

     

    아래 코드에서 수정된 Index view HTML <label> 태그를 렌더링 하기 위해 LabelHelper을 사용합니다.

    주의! <%@ Import Namespace="MvcApplication1.Helpers" %>

     

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index2.aspx.cs"

     Inherits="MvcApplication1.Views.Home.Index2"%>

    <%@ Import Namespace="MvcApplication1.Helpers" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >

    <head id="Head1" runat="server">

         <title>Index2</title>

    </head>

    <body>

         <div>

              <% using (Html.BeginForm())

              { %>

                   <%= LabelHelper.Label("firstName", "First Name:") %>

                   <br />

                   <%= Html.TextBox("firstName")%>

                   <br /><br />

                   <%= LabelHelper.Label("lastName", "Last Name:") %>

                   <br />

                   <%= Html.TextBox("lastName")%>

                   <br /><br />

                   <input type="submit" value="Register" />

              <% } %>

         </div>

    </body>

    </html>

     

    Creating HTML Helpers with Extension Methods

     

    사용자가 확장 메소드를 만들 필요가 생길 때, ASP.NET MVC 프레임워크에 포함된 표준 HTML Helpers 처럼 동작하는 HTML Helpers을 만드 -----------

    확장 메소드는 존재하는 클래스에 새로운 메소드를 추가하여 활성화 할 수 있습니다. HTML Helper 메소드를 만들 때, view Html 프로퍼티를 통해 HtmlHelper 클래스에 새로운 메소드를 추가합니다.

     

    아래 코드의 클래스는 Label() 이라는 이름의 HtmlHelper 클래스에 확장 메소드를 추가합니다. 이 클래스에 관해 주의해야 할 사항이 있습니다. 첫 번째는 이 클래스는 static 클래스이기에 사용자는 static 클래스 내에서 확장 메소드를 정의 해야 합니다.

     

    두 번째로 Label() 메소드의 첫 번째 파라메터는 this 키워드에 의해 선행되어 짐을 알아야 합니다. 확장 메소드의 첫 번째 파라메터는 새로운 확장 메소드가 들어가는 클래스를 의미 합니다.

     

    using System;

    using System.Web.Mvc;

     

    namespace MvcApplication1.Helpers

    {

         public static class LabelExtensions

         {

              public static string Label(this HtmlHelper helper, string target, string text)

              {

                   return String.Format("<label for='{0}'>{1}</label>", target, text);

              }

         }

    }

     

    사용자는 확장 메소드를 만들고 성공적으로 어플리케이션을 빌드 했으면, 확장 메소드는 아래와 같이 Visual Studio Intellisense 에 나타날 것입니다.

     


     

    아래 코드에서 수정된 Index view <label> 태그를 렌더링 할 Html.Label() 확장 메소드를 사용합니다.

     

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index3.aspx.cs" Inherits="MvcApplication1.Views.Home.Index3" %>

    <%@ Import Namespace="MvcApplication1.Helpers" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >

    <head id="Head1" runat="server">

         <title>Index3</title>

    </head>

    <body>

         <div>

              <% using (Html.BeginForm())

              { %>

                   <%= Html.Label("firstName", "First Name:") %>   

                   <br />

                   <%= Html.TextBox("firstName")%>

                   <br /><br />

                   <%= Html.Label("lastName", "Last Name:") %>   

                   <br />

                   <%= Html.TextBox("lastName")%>

                   <br /><br />

                   <input type="submit" value="Register" />

              <% } %>

         </div>

    </body>

    </html>



  • Posted by glycerine
    ,
  • Creating a Tasklist Application with ASP.NET MVC
  • Understanding Models, Views, and Controllers
  • Understanding Controllers, Controller Actions, and Action Results
  • Understanding Views, View Data, and HTML Helpers
  • An Introduction to URL Routing
  • Preventing JavaScript Injection Attacks
  • Creating Unit Tests for ASP.NET MVC Applications
  • Using ASP.NET MVC with Different Versions of IIS
  • Creating Custom HTML Helpers
  • Creating Model Classes with LINQ to SQL
  • Displaying a Table of Database Data
  • Creating Page Layouts with View Master Pages
  • Passing Data to View Master Pages
  • Understanding Action Filters
  • 결론적으로 자바스크립트 인젝션을 막는 방법은 HTML.encode() 라는 겁니다!!
    오타나 틀린 내용은 꼭 지적해주세요!

    Preventing JavaScript Injection Attacks

     

    이 튜토리얼의 목적은 사용자가 ASP.NET MVC 어플리케이션에서 어떻게 자바스크립트 인젝션 공격을 막는가 설명하는 것입니다. 이 튜토리얼은 자바스크립트 인젝션 공격을 막는 두 가지 방법에 대해 토의할 것입니다. 화면에 보여줄 데이터를 인코딩 함으로써 어떻게 자바스크립트 인젝션 공격을 막는지 알게 될 것입니다.

     

    What is a JavaScript Injection Attack?

     

    사용자의 입력을 받고 입력에 의해 화면이 다시 보여질 때마다, 웹 사이트는 자바스크립트 인젝션 공격에 오픈 됩니다. 자바스크립트 인젝션 공격에 오픈 된 실제 어플리케이션을 시험해보겠습니다.

     

    아래 사진과 같은 사용자 입력 웹 사이트를 만들었다고 가정합니다. 고객은 사이트에 접속하고, 제품을 사용하고 느낀 경험에 대해 의견을 입력할 수 있습니다. 고객이 그들의 의견을 전송할 때, 의견은 의견 페이지로 다시 보여질 것입니다.

     


     

    고객 의견 웹 사이트는 아래 코드의 controller을 사용합니다. controller Index() Create() 라는 두 actions을 가지고 있습니다.

     

    using System;

    using System.Web.Mvc;

    using CustomerFeedback.Models;

     

    namespace CustomerFeedback.Controllers

    {

         [HandleError]

         public class HomeController : Controller

         {

              private FeedbackDataContext db = new FeedbackDataContext();

     

              public ActionResult Index()

              {

                   return View(db.Feedbacks);

              }

     

              public ActionResult Create(string message)

              {

                   // Add feedback

                   var newFeedback = new Feedback();

                   newFeedback.Message = message;

                   newFeedback.EntryDate = DateTime.Now;

                   db.Feedbacks.InsertOnSubmit(newFeedback);

                   db.SubmitChanges();

     

                   // Redirect

                   return RedirectToAction("Index");

              }

         }

    }

     

    Index() 메소드는 Index view을 보여줄 것입니다. 이 메소드는 데이터베이스로부터 의견을 가져와 Index view 로 고객 의견을 전달합니다.

     

    Create() 메소드는 새로운 Feedback 개체를 만들고 그것을 데이터베이스에 저장합니다. 고객이 폼에서 입력한 메시지는 message 파라메터로써 Create() 메소드에 전달됩니다. Feedback 개체가 생성되고, message은 생성된 feedback 개체의 Message 속성에 값이 입력됩니다. Feedback 개체는 DataContext.SubmitChanges() 호출을 통해 데이터베이스에 전송됩니다. 마지막으로 모든 의견이 보여지는 Index view 페이지로 리다이렉트 됩니다.

     

    Index view은 다음 코드를 가지고 있습니다.

     

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"

       CodeBehind="Index.aspx.cs" Inherits="CustomerFeedback.Views.Home.Index"%>

     

    <%@ Import Namespace="CustomerFeedback.Models" %>

     

    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

         <h1>Customer Feedback</h1>

         <p>

              Please use the following form to enter feedback about our product.

         </p>

     

         <form method="post" action="/Home/Create">

              <label for="message">Message:</label>

              <br />

              <textarea name="message" cols="50" rows="2"></textarea>

              <br /><br />

              <input type="submit" value="Submit Feedback" />

         </form>

     

         <% foreach (Feedback feedback in ViewData.Model)

         {%>

              <p>

              <%=feedback.EntryDate.ToShortTimeString()%>

              --

              <%=feedback.Message%>

              </p>

         <% }%>

    </asp:Content>

     

    Index view은 두 가지 영역으로 나뉩니다. 상단은 고객 의견 폼이고, 하단은 이전 저장된 고객 의견 아이템을 보여줄 For..Each 루프 영역입니다.

     

    고객 의견 웹 사이트는 간단한 사이트로, 불행히도 자바스크립트 인젝션 공격에 노출되어 있습니다.

     

    고객 의견 폼에서 다음과 같은 문자를 입력한다고 생각해보세요.

    <script>alert(“Boo!”)</script>

     

    이 문자는 경고 메시지 박스를 띄우는 자바스크립트입니다. 누군가 의견 폼에 이 스크립트를 입력하고 전송을 누르면 앞으로 누구든지 이 사이트에 방문하게 되면 메시지 박스 Boo! 가 나타날 것입니다.




    자바스크립트 인젝션 공격에 대한 당신의 초기 반응은 무관심일지도 모릅니다. 아마 자바스크립트 인젝션 공격은 화면을 공격하는 단순한 유형으로 생각할 것입니다. 자바스크립트 인젝션 공격으로 실제로 어떠한 것도 할 수 없다고 생각해보세요.

     

    불행이 해커는 실제로 웹 사이트에 자바스크립트 인젝션으로 사이트를 마비시킬 수 있습니다. Cross-Site Scripting (XSS) 공격을 하기 위해 자바스크립트 인젝션을 사용할 수 있습니다. Cross-Site Scripting 공격으로, 사용자의 정보를 훔칠 수 있고, 다른 웹 사이트로 정보를 보낼 수도 있습니다.

     

    예를 들어, 해커는 다른 유저로부터 브라우저 쿠키 값을 훔칠 수도 있습니다. 비밀번호, 주민등록번호, 또는 신용 카드 번호와 같은 중요한 정보가 쿠키에 저장되어 있다면, 해커들은 그 정보를 알아낼 수 있습니다. 사용자가 자바스크립트 공격에 노출된 페이지에 있는 입력 폼에 정보를 입력한다면, 해커는 자바스크립트 인젝션 공격으로 정보를 가로채 다른 웹 사이트로 보낼 것입니다.

     

    자바스크립트 인젝션 공격은 신중히 처리해야 하고, 사용자의 중요한 정보는 보호해야 할 것입니다. 다음 두 영역에서, 당신이 자바스크립트 인젝션 공격으로부터 ASP.NET MVC 어플리케이션을 보호할 수 있는 두 기술을 이야기 할 것입니다.

     

    Approach #1: HTML Encode in the View

     

    자바스크립트 인젝션 공격을 막는 쉬운 방법은 사용자가 입력한 데이터가 view에 보여질 때, 입력한 데이터를 HTML 인코딩 하는 것입니다. 다음 코드의 수정된 Index view을 보세요..

     

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="CustomerFeedback.Views.Home.Index"%>

     

    <%@ Import Namespace="CustomerFeedback.Models" %>

     

    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

         <h1>Customer Feedback</h1>

         <p>

              Please use the following form to enter feedback about our product.

         </p>

     

         <form method="post" action="/Home/Create">

              <label for="message">Message:</label>

              <br />

              <textarea name="message" cols="50" rows="2"></textarea>

              <br /><br />

              <input type="submit" value="Submit Feedback" />

         </form>

     

         <% foreach (Feedback feedback in ViewData.Model)

         {%>

              <p>

              <%=feedback.EntryDate.ToShortTimeString()%>

              --

              <%=Html.Encode(feedback.Message)%>

              </p>

         <% }%>

    </asp:Content>

     

    Feedback.Message의 값은 아래와 같은 코드로 값이 화면에 출력되기 전에 HTML 로 인코딩 되었습니다.

     

    <%=Html.Encode(feedback.Message)%>

     

    HTML을 문자로 인코딩한다는 것은 무엇을 의미하는 것일까? HTML을 문자로 인코딩 할 때, 위험한 문자는, 예를 들어 < >, HTML entity reference , 예를 들어 &lt; &gt; 로 바뀝니다. 그래서, 문자열 <script>alert(“Boo!”)</script> HTML 인코딩 되면, &lt;script&gt;alert(&quot;Boo!&quot;)&lt;/script&gt;. 로 바뀌게 된다. 인코딩 된 문자는 더 이상 자바스크립트로 실행되지 않습니다.

     

     

    Approach #2: HTML Encode in the Controller

     

    view에서 데이터가 화면에 보여질 때, HTML 인코딩 된 데이터 대신, 데이터베이스에 데이터를 전송하기 전에 데이터를 HTML 인코딩 할 수도 있습니다. 두 번째 방안은 아래의 코드처럼 controller 의 경우입니다.

     

    using System;

    using System.Web.Mvc;

    using CustomerFeedback.Models;

    namespace CustomerFeedback.Controllers

    {

         [HandleError]

         public class HomeController : Controller

         {

              private FeedbackDataContext db = new FeedbackDataContext();

     

              public ActionResult Index()

              {

                   return View(db.Feedbacks);

              }

     

              public ActionResult Create(string message)

              {

                   // Add feedback

                   var newFeedback = new Feedback();

                   newFeedback.Message = Server.HtmlEncode(message);

                   newFeedback.EntryDate = DateTime.Now;

                   db.Feedbacks.InsertOnSubmit(newFeedback);

                   db.SubmitChanges();

     

                   // Redirect

                   return RedirectToAction("Index");

              }

         }

    }

     

    Message의 값이 Create() action 내에서 데이터베이스로 전송되기 전에 HTML 인코딩 된 것을 확인해야 합니다. Message view에 다시 보여질 때, Message HTML 인코딩 되고, 자바스크립트 인젝션도 실행되지 않을 것입니다.

     

    전형적으로, 두 번째 접근 방식보다 첫 번째 접근 방식을 선호합니다. 두 번째 방식의 문제는 데이터베이스에 HTML 인코딩 된 데이터가 들어가는 것입니다. 다른 말로, 데이터베이스의 데이터가 보기에 좋지 않은 문자들로 가득할 것입니다.

     

    이것이 왜 나쁜 것일까요? 웹 페이지에서 더 이상 이 데이터베이스의 데이터를 표시할 필요가 없을 경우 문제가 생길 수 있습니다. 예를 들어 윈도우 어플리케이션에서 사용할 때 입니다.

    Posted by glycerine
    ,

  • Creating a Tasklist Application with ASP.NET MVC
  • Understanding Models, Views, and Controllers
  • Understanding Controllers, Controller Actions, and Action Results
  • Understanding Views, View Data, and HTML Helpers
  • An Introduction to URL Routing
  • Preventing JavaScript Injection Attacks
  • Creating Unit Tests for ASP.NET MVC Applications
  • Using ASP.NET MVC with Different Versions of IIS
  • Creating Custom HTML Helpers
  • Creating Model Classes with LINQ to SQL
  • Displaying a Table of Database Data
  • Creating Page Layouts with View Master Pages
  • Passing Data to View Master Pages
  • Understanding Action Filters


    An Introduction to URL Routing

     

    이 튜토리얼에서, URL Routing이라 불리는 ASP.NET MVC 어플리케이션이 중요한 특징에 관해 설명할 것입니다. URL Routing 모듈은 특정 MVC controller actions에 대한 브라우저 요청을 매핑 합니다.

     

    이 튜토리얼 처음에, 표준 route table이 어떻게 controller actions에 요청을 매핑 하는지 배울 것 입니다. 두 번째로, 기본 route table을 어떻게 수정하고 적용하는지 배울 것 입니다.

     

    Using the Default Route Table

     

    새로운 ASP.NET MVC 어플리케이션을 만들면, 어플리케이션은 이미 URL Routing을 사용할 준비를 해놓습니다. URL Routing은 두 단계 준비작업이 있습니다.

     

    첫 번째로, URL Routing은 어플리케이션의 웹 구성 파일(Web.config file)에 활성화 됩니다. 구성 파일에는 routing에 상응하는 4가지 영역이 있습니다. system.web.httpModules 영역, system.web.httpHandlers 영역, system.webserver.modules 영역, 그리고 system.webserver.handlers 영역이 해당되는데 이 영역이 없으면 동작을 안 하기에 삭제에 신중해야 합니다.

     

    두 번째로, 중요한 부분으로서, route table은 어플리케이션의 Global.asax 파일에 생성됩니다. 이 파일은 ASP.NET 어플리케이션 생명주기 이벤트와 관련된 이벤트 핸들러로 구성된 특별한 파일입니다. Route table은 어플리케이션 시작 이벤트가 발생할 때 만들어 집니다.

     

    다음 코드는 ASP.NET MVC 어플리케이션에 포함된 기본 Global.asax 입니다.

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.Mvc;

    using System.Web.Routing;

     

    namespace MyApp

    {

         public class GlobalApplication : System.Web.HttpApplication

         {

              public static void RegisterRoutes(RouteCollection routes)

              {

                   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

                   routes.MapRoute(

                        "Default", // Route name

                        "{controller}/{action}/{id}", // URL with parameters

                        new { controller = "Home", action = "Index", id = ""}

                        // Parameter defaults );

              }

     

              protected void Application_Start()

              {

                   RegisterRoutes(RouteTable.Routes);

              }

         }

    }

     

    ASP.NET MVC 어플리케이션이 처음 시작할 때, Application_Start() 메소드가 실행됩니다. 이 메소드는, RegisterRoutes() 메소드를 호출하고, RegisterRoutes() 메소드가 route table을 생성합니다.

     

    기본 route table Default라는 이름의 single route 로 구성됩니다. Default route URL의 첫 번째 구분을 controller name과 매핑 시키고, 두 번째 구분을 URL controller action과 매핑 시킵니다. 그리고 세 번째 구분을 id 라는 파라메터로 매핑 시킵니다.

     

    웹 브라우저 주소 바에 다음 URL의 입력을 생각해보세요.

    /Home/Index/3

     

    Default route은 다음 파라메터들로 매핑 시킵니다.

    Controller = Home

    Action = Index

    Id = 3

     

    URL /Home/Index/3을 요청할 때, 다음 코드가 실행됩니다.

    HomeController.Index(3)

     

    Default route 3가지 파라메터는 기본값을 가지고 있습니다. Controller가 빠졌다면 controller 파라메터의 기본값인 Home이 적용됩니다. Action이 빠졌다면, action 파라메터의 기본값인 Index가 적용됩니다. 마지막으로 id 파라메터가 빠졌다면, 기본값인 공백 string이 적용됩니다.

     

    아래의 URL을 브라우저 주소 창에 입력하면 Default route controller actions에 어떻게 매핑 시킬지 생각해보세요.

    /Home

     

    Default route 파라메터가 기본값으로 설정하여, 아래 코드의 HomeController 클래스의 Index() 메소드가 실행될 것입니다.

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.Mvc;

     

    namespace MyApp.Controllers

    {

         [HandleError]

         public class HomeController : Controller

         {

              public ActionResult Index(string Id)

              {

                   return View();

              }

         }

    }

     

    위 코드에서, HomeController 클래스는 Id라는 단일 파라메터를 받는 Index() 메소드를 포함하고 있습니다. URL /Home id 파라메터를 공백으로 Index() 메소드를 호출할 것입니다.

     

    ASP.NET MVC 프레임워크는 controller actions을 호출 하기 때문에, URL /Home은 아래 코드의 HomeController 클래스에 있는 Index() 메소드와 매치 시킵니다.

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.Mvc;

     

    namespace MyApp.Controllers

    {

         [HandleError]

         public class HomeController : Controller

         {

              public ActionResult Index()

              {

                   return View();

              }

         }

    }

     

    위의 Index() 메소드는 어떠한 파라메터도 받지 않습니다. URL /Home이 호출될 때, Index() 메소드를 부릅니다. URL /Home/Index/3 이 입력된다면 아이디를 무시하고 이 메소드가 불려질 것입니다.

     

    URL /Home은 항상 다음 코드의 HomeController 클래스 내의 Index() 메소드로 처리될 것입니다.

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.Mvc;

     

    namespace MyApp.Controllers

    {

         [HandleError]

         public class HomeController : Controller

         {

              public ActionResult Index(int? id)

              {

                   return View();

              }

         }

    }

     

    위 코드에서, Index() 메소드는 하나의 정수형 파라메터를 가지고 있습니다. 파라메터가 nullable 파라메터이기 때문에, Index() 메소드는 에러 발생 없이 호출될 것입니다.

     

    마지막으로, 다음 코드에서 URL /Home으로 인하여 Index() 메소드가 불려지면, Id Parameter nullable 파라메터가 아니라는 에러가 발생됩니다.

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.Mvc;

     

    namespace MyApp.Controllers

    {

         [HandleError]

         public class HomeController : Controller

         {

              public ActionResult Index(int id)

              {

                   return View();

              }

         }

    }

      

    한편으로, URL /Home/Index/3은 위 코드에서 잘 작동합니다. 3은 파라메터 값으로 전달되어 Index() 메소드가 호출 될 것입니다.

     

    Creating a Custom Route

     

    ASP.NET MVC 어플리케이션을 위해, 기본 route table은 잘 작동 할 것입니다. 하지만, 특별한 routing에 대한 요구에 대하여 custom route을 만들 수도 있습니다.

     

    예를 들어 블로그 어플리케이션을 만든다고 가정합시다. 아래와 같은 요청을 처리 해봅시다.

    /Archive/12-25-2009

     

    사용자가 이와 같은 요청을 했을 때, 12/25/2009 에 응답하는 블로그를 원합니다. 이런 유형의 요청을 다루기 위해서, custom route을 만들 필요가 있습니다.

     

    아래의 Global.asax 파일은 /Archive/entry date 와 같은 요청을 다루는 Blog라는 이름의 새로운 custom route을 가지고 있습니다.

     

    using System.Web.Mvc;

    using System.Web.Routing;

     

    namespace MyApp

    {

         public class GlobalApplication : System.Web.HttpApplication

         {

              public static void RegisterRoutes(RouteCollection routes)

              {

                   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

                   routes.MapRoute(

                        "blog",

                        "Archive/{entryDate}",

                        new {controller = "Archive", action = "Entry"}

                        );

                   routes.MapRoute(

                        "Default", // Route name

                        "{controller}/{action}/{id}", // URL with parameters

                        new { controller = "Home", action = "Index", id = ""}

                        // Parameter defaults );

              }

     

              protected void Application_Start()

              {

                   RegisterRoutes(RouteTable.Routes);

              }

         }

    }

     

    Route table에 추가한 route의 순서는 매우 중요합니다. Blog라는 새로운 custom route Default route 전에 추가 해야 합니다. 순서가 바뀐다면, Default route은 항상 custom route 대신 호출될 것입니다.

     

    Custom Blog route은 다음과 같은 /Archive 로 시작하는 요청을 처리 할 것입니다.

    /Archive/12-25/2009

    /Archive/10-6-2004

    /Archive/apple

     

    Custom route Archive controllerEntry() action에 매핑 될 것입니다. Entry() 메소드가 호출되면, entryDate 파라메터로 전달될 것입니다.

     

    Blog custom route을 다음 코드의 controller 로 사용할 수 있습니다.

     

    using System;

    using System.Web.Mvc;

     

    namespace MyApp.Controllers

    {

         public class ArchiveController : Controller

         {

              public string Entry(DateTime entryDate)

              {

                   return "You requested the entry on " + entryDate.ToString();

              }

         }

    }

     

    위 코드에서 Entry() 메소드는 DateTime 타입의 파라메터를 받는다는 것을 확인하세요. ASP.NET MVC 프레임워크는 자동적으로 URL의 날짜를 DateTime 타입으로 변환해줍니다. URL에 날짜 입력 값이 DateTime으로 변환될 수 없다면, 에러가 발생됩니다.


  • Posted by glycerine
    ,