2009-10-20 5 views
4

누군가가 경로가 MVC 2의 컨트롤러와 어떻게 연결되는지 설명 할 수 있습니까? 현재 /Controllers/HomeController.cs에 컨트롤러가 있고 /Home/Index.aspx 뷰가 있습니다.ASP.NET MVC 2 URL/경로는 어떻게 컨트롤러와 관련이 있습니까?

내 경로 등록 방법은 다음과 같습니다

public static void RegisterRoutes(RouteCollection routes) 
     { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
      routes.IgnoreRoute("{resource}.aspx/{*pathInfo}"); 
      routes.MapRoute(
       "Default", 
       // Route name 
       "{controller}/{action}/{id}", 
       // URL with parameters 
       new { controller = "Home", action = "Index", id = "" } 
       // Parameter defaults 
      ); 
     } 

나는 URL 요청하는 경우 : http://localhost/Home/Index, 그 요청이 제대로 HomeController.Index에 의해 처리된다().

그러나 내 인생에서 url/Home/Index가 HomeController를 가리키는 방식을 이해할 수 없습니다. 보기 aspx, 내가 말할 수있는 한 HomeController 참조, HomeController보기를 참조하지 않는 및 경로 테이블에 명시 적으로 HomeController 언급하지 않습니다. 어떻게 이런 일이 일어나는거야? 확실히 나는 명백한 무엇인가 놓치고있다. 액션 색인 내부 다음

답변

5

ASP.NET MVC와 함께 제공되는 기본보기 엔진은 다음과 같은 규칙에 작동합니다

당신은 폴더 구조를 다음과 같이 있습니다

- Controllers\ 
|- HomeController.cs 
- Views\ 
|- Home\ 
|-- Index.aspx 
|- Shared\ 

요청이 들어오고, 경로와 일치

(그 이상에 URL routing 등을 참조) RegisterRoutes 방법으로 정의하고 정합 제어기라고 : 기본 경로에서

routes.MapRoute(
    "Default", // Route name, allows you to call this route elsewhere 
    "{controller}/{action}/{id}", // URL with parameters 
    new { controller = "Home", action = "Index", id = "" } // Parameter defaults 
); 

, "컨트롤러"접미사가없는 기본 컨트롤러도 지정하고 있습니다. 라우팅 엔진이 컨트롤러 이름에 Controller을 자동으로 추가하고 기본 동작을 지정합니다. 컨트롤러에서

, 당신은 간단한 방법을 호출

기본보기 엔진이 다음 "홈"이라는 폴더 지수 (활동과 같은)라는 영문 파일 (같은 찾습니다
public ActionResult Index(){ 
    return View(); 
} 

"보기"폴더 (관례)에있는 컨트롤러로).

하나도 찾지 못하면 공유 폴더에서 색인 페이지를 찾습니다. 뷰 템플릿을 해석 할 때 기본적으로 ASP.NET MVC Nerd Dinner sample chapter

ASP.NET MVC 응용 프로그램에서

은 규칙 기반 디렉토리 이름 구조를 사용합니다. 이를 통해 개발자는 Controller 클래스 내에서 뷰를 참조 할 때 위치 경로를 완전히 한정하지 않아도됩니다. 기본적으로 ASP.NET MVC는 응용 프로그램 아래의 \Views\[ControllerName]\ 디렉토리에있는 뷰 템플릿 파일을 찾습니다.

하위 디렉토리 \Views\Shared 하위 디렉토리는 응용 프로그램 내의 여러 컨트롤러에서 다시 사용되는보기 템플리트를 저장할 수있는 방법을 제공합니다. ASP.NET MVC가 뷰 템플릿을 분석하려고 시도하면 먼저 \Views\[Controller] 특정 디렉토리를 검사하고 뷰 템플릿을 찾을 수 없으면 \Views\Shared 디렉토리에서 찾습니다.

개별보기 템플리트의 이름을 지정할 때보기 템플리트가 렌더링하게 한 조치 메소드와 동일한 이름을 공유하도록하는 것이 좋습니다. 예를 들어, "Index"액션 메소드는 "Index"뷰를 사용하여 뷰 결과를 렌더링하고, "Details"액션 메소드는 "Details"뷰를 사용하여 결과를 렌더링합니다. 이렇게하면 각 작업과 관련된 템플리트를 빨리 확인할 수 있습니다.

개발자는보기 템플리트가 컨트롤러에서 호출되는 조치 메소드와 동일한 이름을 가질 때 명시 적으로보기 템플리트 이름을 지정할 필요가 없습니다. 대신 모델 이름을 View() (뷰 이름을 지정하지 않고) 도우미 메서드에 전달하면 ASP.NET MVC는 디스크에 \Views\[ControllerName]\[ActionName] 뷰 템플릿을 사용하여 렌더링하려고한다고 자동으로 추론합니다.


편집 추가 :

내가 설정 한 몇 가지 예를 들어 경로가 명시 적으로 컨트롤러를 설정하는 것이 있습니다 : 여기

routes.MapRoute(
    "PhotoDetailsSlug", 
    "Albums/{albumId}/{photoId}/{slug}", 
    new {controller = "Albums", action = "PhotoDetails"}, 
    new {albumId = @"\d{1,4}", photoId = @"\d{1,8}"} 
); 

내가 명시 적으로 난 것을 주장하고있어 앨범 컨트롤러와 PhotoDetails 액션을 사용하고 다양한 아이디 등을 해당 액션에 전달합니다.

+0

그 중 대부분은 의미가 있습니다. 그러나 두 번째 코드 조각의 .MapRoute로 전달 된 기본 개체는 "집"이라는 컨트롤러를 참조합니다.내 컨트롤러 클래스는 "HomeController"라고합니다. 특정 경로/URL에 사용 된 컨트롤러를 명시 적으로 지정하려면 어떻게해야합니까? –

+0

해당 경로에 대한 명시적인 규칙을 추가하고 사용할 기본 컨트롤러 매개 변수 (컨트롤러 접미사가 적은)를 지정해야합니다. –

+0

감사합니다.이 사실을 받아 들일 것입니다. 그러나 위의 예에서 "Albums"에는 "AlbumsController"라는 컨트롤러 클래스가 있어야한다는 점을 올바르게 이해합니까? –

2

는 성명 return View()있다. 빈 View가 반환되면 DefaultViewEngine은 컨트롤러 메서드의 이름 (특히 FindView 메서드 내부)에 대한 여러 기본 폴더를 검색합니다. 그 중 하나는 홈이 컨트롤러의 이름이기 때문에 Views/Home 디렉토리입니다. 거기서 인덱스 파일을 찾아 결과를 표시하는 데 사용합니다.

+0

올바른보기가 어떻게 발견되는지를 설명하지만, 올바른 컨트롤러 메소드는 어떻게 실행됩니까? –

6

이것은 ASP.NET MVC의 규칙입니다.

DefaultControllerFactory를 사용할 때이 규칙은 내부 밀폐 된 클래스 System.Web.Mvc.ControllerTypeCache (일반적으로 내부 밀폐 된 클래스를 작성하는 Microsoft)에 묻혀 있습니다. 그룹화가 어떻게 만들어 지는지

public void EnsureInitialized(IBuildManager buildManager) 
{ 
    if (this._cache == null) 
    { 
     lock (this._lockObj) 
     { 
      if (this._cache == null) 
      { 
       this._cache = GetAllControllerTypes(buildManager).GroupBy<Type, string>(delegate (Type t) { 
        return t.Name.Substring(0, t.Name.Length - "Controller".Length); 
       }, StringComparer.OrdinalIgnoreCase).ToDictionary<IGrouping<string, Type>, string, ILookup<string, Type>>(delegate (IGrouping<string, Type> g) { 
        return g.Key; 
       }, delegate (IGrouping<string, Type> g) { 
        return g.ToLookup<Type, string>(t => t.Namespace ?? string.Empty, StringComparer.OrdinalIgnoreCase); 
       }, StringComparer.OrdinalIgnoreCase); 
      } 
     } 
    } 
} 

에주의 : 당신의 내부에서 다음과 같습니다 EnsureInitialized라는 방법을 찾을 수 있습니다. 그래서 기본적으로 DefaultControllerFactory는 Controller 기본 클래스를 구현하는 유형에 대해 참조 된 모든 어셈블리를 조사하고 이름에서 "Controller"를 제거합니다.

자세한 내용은 ASP.NET MVC의 파이프 라인을 참조하십시오.이 excellent article을 추천합니다.

+0

그것은 기괴합니다. 컨트롤러 클래스의 이름은 URL과 관련이 있어야합니다! 컨트롤러 이름이없는 URL에 동일한 컨트롤러를 사용하려면 어떻게해야합니까? –

+1

라우팅 테이블에 다음과 같이 지정합니다 :'routes.MapRoute ("MyRoute", "someSpecialUrl/blabla", new (controller = "Home", action = "Index", id = ""}); 사용할 컨트롤러를 지정해야합니다. –

+0

또한 StringComparer.OrdinalIgnoreCase 플래그가 설정되어 있으면 해당 프레임 워크가 HomeController와 homecontroller를 구별 할 수 없다는 의미가 아닙니까? –