2010-03-08 6 views
10

간단한 ASP.NET MVC 버전 1.0 응용 프로그램을 만들었습니다. 하나의 액션 인덱스가있는 ProductController가 있습니다. 보기에서 Product 하위 폴더에 해당 Index.aspx를 만들었습니다.ASP.NET MVC 뷰 엔진 해상도 시퀀스

그런 다음 Spark dll을 참조하고 동일한 Product보기 폴더에서 Index.spark를 만들었습니다. 내 기대는 제품 컨트롤러에서 색인 작업을 탐색 할 때 기본 WebFormViewEngine 전에 점화 엔진에 등록하기 때문에, 스파크 엔진을 사용해야하며, WebFormViewEngine 다른 모든 URL을 사용해야합니다

protected void Application_Start() 
    { 
     RegisterRoutes(RouteTable.Routes); 

     ViewEngines.Engines.Clear(); 
     ViewEngines.Engines.Add(new Spark.Web.Mvc.SparkViewFactory()); 

     ViewEngines.Engines.Add(new WebFormViewEngine()); 

    } 

것처럼 위해 Application_Start 보인다.

그러나이 테스트에서는 Product 컨트롤러의 Index 작업도 WebFormViewEngine을 사용함을 보여줍니다.

WebFormViewEnginer (코드의 마지막 줄) 등록을 주석 처리하면 Spark 엔진에서 색인 작업이 렌더링되고 나머지 URL이 오류를 생성한다는 것을 알 수 있습니다 (기본 엔진이 없어짐). 내 모든 스파크 코드가 정확하다는 것을 증명합니다.

이제 내 질문은 뷰 엔진이 어떻게 해결 되었습니까? 등록 순서가 유효하지 않은 이유는 무엇입니까?

답변

18

뷰 엔진을 등록하는 순서는 중요하지 않습니다. 오히려보기 엔진은 ViewLocationFormats 세트를 사용하며 특정보기 경로가 형식화 된 이름에 맞으면 해당 엔진이 사용됩니다. 충돌하는 형식이있는 경우에만 등록 순서가 중요합니다.

스파크의 경우보기의 길이는 .spark이어야합니다. WebFormViewEngine.aspx 또는 .ascx 개의 확장 프로그램에 응답합니다. 물론 위에서 언급 한 것처럼 개별 뷰 엔진에 제공된 ViewLocationFormats을 변경하여이 중 하나를 재정의 할 수 있습니다.

내가 모두 SparkViewFactoryWebFormViewEngine의 소스 (또는 더 구체적으로, VirtualPathProviderViewEngine에서 후자의 도출)을 통해 살펴 보았다, 그리고 당신이있어 내가 왜 당신을 말할 수 있습니다


업데이트 이 이상한 행동을 봅니다. 모든

첫째, ViewEngineCollection 클래스의 Find 방법은 (간체)과 같이 작동합니다 : 즉

foreach (IViewEngine engine in Items) { 
    // Query engine for cached view 
} 

foreach (IViewEngine engine in Items) { 
    // Query engine for uncached view 
} 

, 항상 캐시를 찾을 것을 시도 할 것이다, 의 모든 엔진을하기 전에 캐시되지 않은 모드를 사용합니다.

개별보기 엔진이 구현하는 방식은 인수가 useCacheFindView 메서드의 두 번째 오버로드입니다. 모든 이상한 얻을 경우 여기

그러나, 그리고이다 - VirtualPathProviderViewEngineSparkViewEngineuseCache 인수가 무엇을 의미하는지 매우 다른 생각을 가지고있다.여기의 재 게시 너무 많은 코드는하지만 기본적인 아이디어는 다음과 같습니다 useCachetrue 경우

  • SparkViewFactory가 캐시에 을 찾을 것입니다. 아무것도 찾지 못하면 자동으로 "캐시 미스 결과"를 반환합니다 (즉, 아무것도 표시하지 않음). 반면에 useCachefalse이면 캐시에서 전혀 보지 않고 캐시 확인 단계를 건너 뛰고 정상적인 동작을 통해 실제보기를 확인하고 만듭니다. useCachetrue 경우 VirtualPathProviderViewEngine

  • , 다른 한편으로는, 캐시에 보이는, 그리고 캐시에서보기를 찾을 수없는 경우, 이 꺼지고 새로 만들고 캐시 것을 추가 . 이러한 접근 방식의

모두 ViewEngineCollection이 검색을 수행하는 방법에 대해 작동합니다. 스파크의 경우

  • , 제 뷰 엔진 반복하지만, 상기 제의 "히트"에 대한 상기 뷰가 캐시에 추가되어 그 후에 "미스". 문제 없어.

  • VirtualPathProviderViewEngine의 경우 내부적으로 "누락"되지만 어쨌든 첫 번째 반복에서 "히트"를 반환합니다.이 시점에서보기가 현재 캐시됩니다.

여기에서 문제가있는 곳을 확인할 수 있습니다. VirtualPathProviderViewEngine이 전 항상 (캐시) 반복에 성공 때문에 SparkViewEngine보다 우선 순위를 가지고 있지만이 (캐시되지 않은) 반복에 성공 스파크 것으로 보인다.

영어로 말하면, Spark이 실제로 먼저 질문을 받지만 대답은 "아니요,보기가 없습니다 아직입니다. 대신 캐시없이 사용해보십시오." WebForms가 두 번째로 요청되지만 자동으로 이 표시됩니다. "이 아니지만 그보기를 가지고 있지만 어쨌든 하나 만들었습니다. 여기 있습니다.". 그리고 그 시점부터 WebFormViewEngine은 캐시 된 뷰를 가지고 있고 Spark은 캐시되지 않기 때문에 항상 우선 순위를 얻습니다.


요약 : 스파크 웹 양식 엔진이 동시에 활성화 될 때 그것은 먼지에 남아 점점, 점점 우선 순위이지만, 방식 때문에 불꽃의 특질에 useCache 인수를 처리합니다. WebForm이 지나치게 열성적이거나 Spark가 사용자의 관점에 따라 게으르다.

간단히 말해 해결 방법이 충돌하지 않는 입니다. 여러 뷰 엔진을 등록한 경우 두 가지 중 하나 또는 둘 모두에서 처리 할 수있는 뷰 이름을 정의되지 않은 동작으로 처리해야합니다.

+0

요약 : Index.aspx 파일을 제거하면 Index.spark가 사용됩니다. – LukLed

+0

나는 아직도 이해하지 못한다. ViewLocationFormats는 VirtualPathProviderViewEngine에 정의되어 있으며 뷰 엔진 고유의 내부 구현입니다. ASP.NET MVC에 등록 된 여러 뷰 엔진이 있으면 뷰 엔진이 요청을 처리 할 수 ​​있는지 여부를 하나씩 쿼리합니다. 첫 번째 뷰 엔진은 요청을 처리합니다. 제 경우에는 Spark와 WebFormViewEngine이 Index.aspx와 Index.spark가 있기 때문에 요청을 처리 할 수 ​​있습니다. 그렇다면 왜 WebForViewEngine을 우선시합니까? – intangible02

+0

@ intangible02 : 테스트를 거쳐 검증되었으므로, 근원을 파헤 치고 그에 대한 설명이 있습니다. – Aaronaught

1

흠 ... 아니요. 모든 기준을 준수하는 webform은 useCache가 true 일 때 캐시 검사를 넘어 아무것도하지 않습니다. 스파크와 동일합니다.

실제로 - 나는 누군가 내 치즈를 옮겼을지도 모른다고 생각한다. 스파크는 useCache == true pass 중에 잘못된 캐시 미스를 일으키는 버크를 추가했을지도 모른다. 그것이 사실이라면 그 매개 변수에 적용된 다른 규칙보다 버그가 더 많습니다.


업데이트 : 나는 원래 MVC 2를 찾고 있었어요

- Aaronaught의 결론이 잘못되었습니다 @ 내가 암시하는 이유입니다. MVC 2는 useCache == true 인 첫 번째 패스에서 뷰를 반환하지 않으며, MVC 1.0에서는 해결되어 채워집니다.

ASP.NET MVC 1.0과 ASP.NET MVC 2의 차이점은 다음과 같습니다. Spark과 MVC 2는 useCache 플래그를 동일하게 처리하고 등록 된 순서에 우선 순위를 부여합니다.

관련 문제