Share via


URL 라우팅

작성자 : Erik Reitan

Wingtip Toys 샘플 프로젝트 다운로드(C#) 또는 전자책 다운로드(PDF)

이 자습서 시리즈에서는 웹용 ASP.NET 4.5 및 Microsoft Visual Studio Express 2013을 사용하여 ASP.NET Web Forms 애플리케이션을 빌드하는 기본 사항을 설명합니다. C# 소스 코드가 포함된 Visual Studio 2013 프로젝트는 이 자습서 시리즈와 함께 사용할 수 있습니다.

이 자습서에서는 URL 라우팅을 지원하도록 Wingtip Toys 샘플 애플리케이션을 수정합니다. 라우팅을 사용하면 웹 애플리케이션이 검색 엔진에서 친숙하고 기억하기 쉽고 더 잘 지원되는 URL을 사용할 수 있습니다. 이 자습서는 이전 자습서 "멤버 자격 및 관리"를 기반으로 하며 Wingtip Toys 자습서 시리즈의 일부입니다.

학습할 내용:

  • ASP.NET Web Forms 애플리케이션에 대한 경로를 등록하는 방법입니다.
  • 웹 페이지에 경로를 추가하는 방법입니다.
  • 경로를 지원하기 위해 데이터베이스에서 데이터를 선택하는 방법입니다.

ASP.NET 라우팅 개요

URL 라우팅을 사용하면 물리적 파일에 매핑되지 않는 요청 URL을 수락하도록 애플리케이션을 구성할 수 있습니다. 요청 URL은 단순히 사용자가 웹 사이트에서 페이지를 찾기 위해 브라우저에 입력하는 URL입니다. 라우팅을 사용하여 사용자에게 의미상 의미가 있고 SEO(검색 엔진 최적화)에 도움이 될 수 있는 URL을 정의합니다.

기본적으로 Web Forms 템플릿에는 ASP.NET 친숙한 URL이 포함됩니다. 기본 라우팅 작업의 대부분은 친숙한 URL을 사용하여 구현됩니다. 그러나 이 자습서에서는 사용자 지정된 라우팅 기능을 추가합니다.

URL 라우팅을 사용자 지정하기 전에 Wingtip Toys 샘플 애플리케이션은 다음 URL을 사용하여 제품에 연결할 수 있습니다.

https://localhost:44300/ProductDetails.aspx?productID=2

URL 라우팅을 사용자 지정하면 Wingtip Toys 샘플 애플리케이션이 더 쉽게 읽을 수 있는 URL을 사용하여 동일한 제품에 연결됩니다.

https://localhost:44300/Product/Convertible%20Car

경로

경로는 처리기에 매핑되는 URL 패턴입니다. 처리기는 Web Forms 애플리케이션의 .aspx 파일과 같은 물리적 파일일 수 있습니다. 처리기는 요청을 처리하는 클래스일 수도 있습니다. 경로를 정의하려면 URL 패턴, 처리기 및 필요에 따라 경로 이름을 지정하여 Route 클래스의 instance 만듭니다.

클래스의 정적 Routes 속성에 개체를 Route 추가하여 애플리케이션에 경로를 추가합니다RouteTable. Routes 속성은 애플리케이션에 RouteCollection 대한 모든 경로를 저장하는 개체입니다.

URL 패턴

URL 패턴에는 리터럴 값과 변수 자리 표시자(URL 매개 변수라고 함)가 포함될 수 있습니다. 리터럴 및 자리 표시자는 슬래시(/) 문자로 구분된 URL의 세그먼트에 있습니다.

웹 애플리케이션에 대한 요청이 이루어지면 URL이 세그먼트 및 자리 표시자로 구문 분석되고 변수 값이 요청 처리기에 제공됩니다. 이 프로세스는 쿼리 문자열의 데이터가 구문 분석되어 요청 처리기에 전달되는 방식과 유사합니다. 두 경우 모두 변수 정보가 URL에 포함되고 키-값 쌍의 형태로 처리기에 전달됩니다. 쿼리 문자열의 경우 키와 값은 모두 URL에 있습니다. 경로의 경우 키는 URL 패턴에 정의된 자리 표시자 이름이고 값만 URL에 있습니다.

URL 패턴에서 자리 표시자를 중괄호( {} )로 묶어 정의합니다. 세그먼트에서 둘 이상의 자리 표시자를 정의할 수 있지만 자리 표시자는 리터럴 값으로 구분해야 합니다. 예를 들어 는 {language}-{country}/{action} 유효한 경로 패턴입니다. 그러나 {language}{country}/{action} 는 자리 표시자 사이에 리터럴 값 또는 구분 기호가 없으므로 유효한 패턴이 아닙니다. 따라서 라우팅은 언어 자리 표시자의 값을 국가 자리 표시자의 값과 구분할 위치를 결정할 수 없습니다.

경로 매핑 및 등록

Wingtip Toys 샘플 애플리케이션의 페이지에 대한 경로를 포함하려면 먼저 애플리케이션이 시작될 때 경로를 등록해야 합니다. 경로를 등록하려면 이벤트 처리기를 수정합니다 Application_Start .

  1. visual Studio의 솔루션 탐색기Global.asax.cs 파일을 찾아 엽니다.

  2. 다음과 같이 노란색으로 강조 표시된 코드를 Global.asax.cs 파일에 추가합니다.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Optimization;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.SessionState;
    using System.Data.Entity;
    using WingtipToys.Models;
    using WingtipToys.Logic;
    
    namespace WingtipToys
    {
        public class Global : HttpApplication
        {
            void Application_Start(object sender, EventArgs e)
            {
              // Code that runs on application startup
              RouteConfig.RegisterRoutes(RouteTable.Routes);
              BundleConfig.RegisterBundles(BundleTable.Bundles);
    
              // Initialize the product database.
              Database.SetInitializer(new ProductDatabaseInitializer());
    
              // Create custom role and user.
              RoleActions roleActions = new RoleActions();
              roleActions.AddUserAndRole();
    
              // Add Routes.
              RegisterCustomRoutes(RouteTable.Routes);
            }
    
            void RegisterCustomRoutes(RouteCollection routes)
            {
              routes.MapPageRoute(
                  "ProductsByCategoryRoute",
                  "Category/{categoryName}",
                  "~/ProductList.aspx"
              );
              routes.MapPageRoute(
                  "ProductByNameRoute",
                  "Product/{productName}",
                  "~/ProductDetails.aspx"
              );
            }
        }
    }
    

Wingtip Toys 샘플 애플리케이션이 시작되면 이벤트 처리기를 Application_Start 호출합니다. 이 이벤트 처리기의 끝에서 메서드가 RegisterCustomRoutes 호출됩니다. 메서드는 RegisterCustomRoutes 개체의 RouteCollection 메서드를 MapPageRoute 호출하여 각 경로를 추가합니다. 경로는 경로 이름, 경로 URL 및 실제 URL을 사용하여 정의됩니다.

첫 번째 매개 변수("ProductsByCategoryRoute")는 경로 이름입니다. 필요할 때 경로를 호출하는 데 사용됩니다. 두 번째 매개 변수("Category/{categoryName}")는 코드에 따라 동적일 수 있는 친숙한 대체 URL을 정의합니다. 데이터를 기반으로 생성된 링크로 데이터 컨트롤을 채울 때 이 경로를 사용합니다. 경로는 다음과 같습니다.

routes.MapPageRoute(
      "ProductsByCategoryRoute",
      "Category/{categoryName}",
      "~/ProductList.aspx"
  );

경로의 두 번째 매개 변수에는 중괄호({ })로 지정된 동적 값이 포함됩니다. 이 경우 는 categoryName 적절한 라우팅 경로를 결정하는 데 사용되는 변수입니다.

참고

선택 사항

메서드를 별도의 클래스로 이동하여 RegisterCustomRoutes 코드를 보다 쉽게 관리할 수 있습니다. Logic 폴더에서 별도의 RouteActions 클래스를 만듭니다. 위의 RegisterCustomRoutes 메서드를 Global.asax.cs 파일에서 새 RoutesActions 클래스로 이동합니다. RoleActionsGlobal.asax.cs 파일에서 메서드를 호출 RegisterCustomRoutes 하는 방법의 예로 클래스와 createAdmin 메서드를 사용합니다.

이벤트 처리기의 시작 부분에서 개체를 RegisterRoutesRouteConfig 사용하여 메서드 호출을 Application_Start 발견했을 수도 있습니다. 이 호출은 기본 라우팅을 구현하기 위해 수행됩니다. Visual Studio의 Web Forms 템플릿을 사용하여 애플리케이션을 만들 때 기본 코드로 포함되었습니다.

경로 데이터 검색 및 사용

위에서 설명한 대로 경로를 정의할 수 있습니다. Global.asax.cs 파일의 Application_Start 이벤트 처리기에 추가한 코드는 정의 가능한 경로를 로드합니다.

경로 설정

경로를 사용하려면 코드를 더 추가해야 합니다. 이 자습서에서는 모델 바인딩을 사용하여 데이터 컨트롤의 RouteValueDictionary 데이터를 사용하여 경로를 생성할 때 사용되는 개체를 검색합니다. 개체에는 RouteValueDictionary 특정 제품 범주에 속하는 제품 이름 목록이 포함됩니다. 데이터 및 경로에 따라 각 제품에 대한 링크가 만들어집니다.

범주 및 제품에 대한 경로 사용

다음으로, 를 사용하여 ProductsByCategoryRoute 각 제품 범주 링크에 포함할 올바른 경로를 결정하도록 애플리케이션을 업데이트합니다. 또한 각 제품에 대한 라우트된 링크를 포함하도록 ProductList.aspx 페이지를 업데이트합니다. 링크는 변경 전과 같이 표시되지만 링크는 이제 URL 라우팅을 사용합니다.

  1. 솔루션 탐색기 아직 열려 있지 않은 경우 Site.Master 페이지를 엽니다.

  2. 변경 내용이 노란색으로 강조 표시된 상태로 "categoryList"라는 ListView 컨트롤을 업데이트하면 태그가 다음과 같이 표시됩니다.

    <asp:ListView ID="categoryList"  
        ItemType="WingtipToys.Models.Category" 
        runat="server"
        SelectMethod="GetCategories" >
        <ItemTemplate>
            <b style="font-size: large; font-style: normal">
            <a href="<%#: GetRouteUrl("ProductsByCategoryRoute", new {categoryName = Item.CategoryName}) %>">
                <%#: Item.CategoryName %>
            </a>
            </b>
        </ItemTemplate>
        <ItemSeparatorTemplate>  |  </ItemSeparatorTemplate>
    </asp:ListView>
    
  3. 솔루션 탐색기ProductList.aspx 페이지를 엽니다.

  4. ItemTemplateProductList.aspx 페이지의 요소를 노란색으로 강조 표시된 업데이트로 업데이트하면 태그가 다음과 같이 표시됩니다.

    <ItemTemplate>
      <td runat="server">
        <table>
          <tr>
            <td>
              <a href="<%#: GetRouteUrl("ProductByNameRoute", new {productName = Item.ProductName}) %>">
                <image src='/Catalog/Images/Thumbs/<%#:Item.ImagePath%>'
                  width="100" height="75" border="1" />
              </a>
            </td>
          </tr>
          <tr>
            <td>
              <a href="<%#: GetRouteUrl("ProductByNameRoute", new {productName = Item.ProductName}) %>">
                <%#:Item.ProductName%>
              </a>
              <br />
              <span>
                <b>Price: </b><%#:String.Format("{0:c}", Item.UnitPrice)%>
              </span>
              <br />
              <a href="/AddToCart.aspx?productID=<%#:Item.ProductID %>">
                <span class="ProductListItem">
                  <b>Add To Cart<b>
                </span>
              </a>
            </td>
          </tr>
          <tr>
            <td>&nbsp;</td>
          </tr>
        </table>
        </p>
      </td>
    </ItemTemplate>
    
  5. ProductList.aspx.cs의 코드 숨김을 열고 노란색으로 강조 표시된 다음 네임스페이스를 추가합니다.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Models;
    using System.Web.ModelBinding;
    using System.Web.Routing;
    
  6. 코드 숨김 GetProducts (ProductList.aspx.cs)의 메서드를 다음 코드로 바꿉니다.

    public IQueryable<Product> GetProducts(
        [QueryString("id")] int? categoryId,
        [RouteData] string categoryName)
    {
        var _db = new WingtipToys.Models.ProductContext();
        IQueryable<Product> query = _db.Products;
    
        if (categoryId.HasValue && categoryId > 0)
        {
            query = query.Where(p => p.CategoryID == categoryId);
        }
    
        if (!String.IsNullOrEmpty(categoryName))
        {
            query = query.Where(p =>
                String.Compare(p.Category.CategoryName,
                categoryName) == 0);
        }
        return query;
    }
    

제품 세부 정보에 대한 코드 추가

이제 경로 데이터를 사용하도록 ProductDetails.aspx 페이지의 코드 숨김( ProductDetails.aspx.cs)을 업데이트합니다. 또한 새 GetProduct 메서드는 사용자에게 이전의 비우호적인 라우팅되지 않은 URL을 사용하는 링크 책갈피가 있는 경우 쿼리 문자열 값도 허용합니다.

  1. 코드 숨김 GetProduct (ProductDetails.aspx.cs)의 메서드를 다음 코드로 바꿉니다.

    public IQueryable<Product> GetProduct(
            [QueryString("ProductID")] int? productId,
            [RouteData] string productName)
    {
        var _db = new WingtipToys.Models.ProductContext();
        IQueryable<Product> query = _db.Products;
        if (productId.HasValue && productId > 0)
        {
            query = query.Where(p => p.ProductID == productId);
        }
        else if (!String.IsNullOrEmpty(productName))
        {
            query = query.Where(p =>
                  String.Compare(p.ProductName, productName) == 0);
        }
        else
        {
            query = null;
        }
        return query;
    }
    

애플리케이션 실행

이제 애플리케이션을 실행하여 업데이트된 경로를 볼 수 있습니다.

  1. F5 키를 눌러 Wingtip Toys 샘플 애플리케이션을 실행합니다.
    브라우저가 열리고 Default.aspx 페이지가 표시됩니다.
  2. 페이지 맨 위에 있는 제품 링크를 클릭합니다.
    모든 제품은 ProductList.aspx 페이지에 표시됩니다. 브라우저에 대해 다음 URL(포트 번호 사용)이 표시됩니다.
    https://localhost:44300/ProductList
  3. 다음으로, 페이지 맨 위에 있는 자동차 범주 링크를 클릭합니다.
    ProductList.aspx 페이지에는 자동차만 표시됩니다. 브라우저에 대해 다음 URL(포트 번호 사용)이 표시됩니다.
    https://localhost:44300/Category/Cars
  4. 페이지에 나열된 첫 번째 자동차 이름("컨버터블 자동차")이 포함된 링크를 클릭하여 제품 세부 정보를 표시합니다.
    브라우저에 대해 다음 URL(포트 번호 사용)이 표시됩니다.
    https://localhost:44300/Product/Convertible%20Car
  5. 다음으로, 브라우저에 다음 라우팅하지 않은 URL(포트 번호 사용)을 입력합니다.
    https://localhost:44300/ProductDetails.aspx?productID=2
    코드는 사용자에게 링크 책갈피가 있는 경우 쿼리 문자열을 포함하는 URL을 계속 인식합니다.

요약

이 자습서에서는 범주 및 제품에 대한 경로를 추가했습니다. 모델 바인딩을 사용하는 데이터 컨트롤과 경로를 통합하는 방법을 알아보았습니다. 다음 자습서에서는 전역 오류 처리를 구현합니다.

추가 리소스

ASP.NET URL
멤버 자격, OAuth 및 SQL Database 사용하여 보안 ASP.NET Web Forms 앱을 배포하여 Azure App Service
Microsoft Azure - 평가판