잊지 않겠습니다.

: RouteBase, Route, RouteCollection

응용프로그램은 하나의 System.Web.Routing.RouteTable.Routes를 가지며, 응용프로그램의
실제 동작하는 Routing 구성 설정을 갖는다.

ASP.NET MVC에서 구성되는 Global.asax에서 application_start()로 구현이 된다.


Route의 동작

1. Url 요청
2. UrlRoutingModule module 호출(System.Web.Routing)
3. System.Web.Routing.RouteTable.Routes 안에서 요청과 일치하는 RouteBase 객체 반환
4. RouteData 구조체 확인
   1) RouteHandler : 요청을 처리할 객체 (ASP .NET MVC에서는 MvcRouteHandler의 instance가 된다.)
   2) RouteValueDictionary : 요청에서 추출된 중괄호 매개변수의 이름과 값의 dictionary
   3) Route : RouteBase에 대한 참조 객체
   4) DataTokens : Routing Entry에 의해 제공되는 모든 추가적인 구성 설정 옵션의 Dictionary
5. RouteData의 RouteHandler 호출
   : RouteHandler에 RouteData, Http Header, Cookie, Auth, Query string, post data를 포함한 모든 HttpContextBase전달

* Route Entry의 순서는 매우 중요하다. System.Web.Routing.RouteTable.Routes는 정렬된 목록이 제공되며,
  이는 Global.asxs 파일안에 정의되어있는 순서대로 구성이 되게 된다. 보다 명확한 매치에 해당되는 Route를
  먼저 등록시켜야지 된다.

* Server의 HDD에 있는 경우에는 언제나 그 정적인 파일이 우선적으로 호출된다. Routing 구성 설정보다
  우선권을 갖게 된다.


기본 Routing 작성


Route defaultRoute = new Route("{controller}/{action}/{id}", new MvcRouteHandler())
{                
    Defaults = new RouteValueDictionary(new { controller = "Home", action = "index", id = "" })
};
routes.Add("default", defaultRoute);

routes.Add(new Route("Catalog/{color}", new MvcRouteHandler())
{
    Defaults = new RouteValueDictionary(
        new { controller = "Products", action = "List", color=(string)null }
        )                
});


제약사항이 있는 Routing 작성
: Constraint를 이용. 제약 사항을 추가적으로 만들어주기 위해서는 System.Web.Routing.IRouteConstraint를
  상속받는 Class를 제공해서 RouteValueDictionary에 넣어주면 된다.


routes.Add(new Route("Article/{id}", new MvcRouteHandler())
{
    Defaults = new RouteValueDictionary(new { controller = "Articles", action = "Show" }),
    Constraints = new RouteValueDictionary(
            new
            {
                id = @"\d{1,6}", //ID 값이 항시 정규표현식 안에 일치하는지 제약조건 강제화.
                httpMethod = new HttpMethodConstraint("GET"), //항시 GET method로만 call이 가능
                userAgent = new UserAgentConstraint("iPhone") //iPhone web agent로만 접근 가능 
            }
        )
});

public class UserAgentConstraint : IRouteConstraint
{
    private string _requestSubString;
    public UserAgentConstraint(string requestSubString)
    {
        _requestSubString = requestSubString;
    }

    #region IRouteConstraint Members

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if(httpContext.Request.UserAgent == null)
            return false;
        return httpContext.Request.UserAgent.Contains(_requestSubString);
    }

    #endregion
}


* 현재 사용의 매개변수는 재사용될 수 있다는 점을 염두해둬야지 된다.이 때 고려될 것은 매개변수보다
  앞쪽에 나오는 매개변수에 대한 값들만이 재사용된다.
  routes.MapRoute(null, "{controller}/{action}/{color}/{page}");  의 경우에,
  <%=Html.ActionLink("ClickMe", "List", "Catalog", new {page=789}, null)%>로 구성이 될 경우에는 color
  값은 ActionLink가 호출이 되는 현재 요청의 color 값이 사용이 된다. 그러나,
  <%=Html.ActionLink("ClickMe", "List", "Catalog", new {color="black"},null%>로 구성이 될 경우에는
  page값이 재사용되지 못하고 route entry는 일치되지 못한다.


Posted by Y2K
,