2012-01-03 2 views
5

일치하는 경로를 가져 오는 데 문제가 있습니다.이 경로가 일치하지 않는 이유

웹 응용 프로그램에서 슬라이드 쇼에 대한 짧은 링크로 base-32로 인코딩 된 int를 사용하고 있습니다. 각 슬라이드 쇼에는 5 가지 버전이 있으며 각 버전을 구별하기 위해 초기 글자를 사용하고 있습니다.

base-32로 인코딩 된 int의 첫 번째 문자가 슬라이드 쇼 버전을 나타내는 문자와 같은 경우를 제외하고는 경로가 항상 일치합니다. 이 변칙은 n, f, c, x 및 h와 같은 5 개의 접두사 문자 모두에 대해 존재합니다.

처음 두 문자가 같으면이 경로가 일치하지 않습니다. 나는 여기서 어떤 일이 벌어지는 지 이해하지 못하고있다. (경로가 일치하지 않으면, 단순히 기본값으로 빠져 든다.)

경로는 (/na0)를 일치 : route for na0

경로는 (/nn0를) 일치하지 않습니다 : route for nn0

경로가 일치 (/nfg를) route for nfg

경로가 일치하지 않습니다 (/ffg를) : route for ffg

나는 놀란다.

 routes.MapRoute(
      "NonBrandedSlideshow", 
      "n{id}", 
      MVC.Slideshow.NonBranded(), null, 
      new { id = Settings.Base32Regex } 
     ); 

     routes.MapRoute(
      "FullSlideshow", 
      "f{id}", 
      MVC.Slideshow.Full(), null, 
      new { id = Settings.Base32Regex } 
     ); 

     routes.MapRoute(
      "CompactSlideshow", 
      "c{id}", 
      MVC.Slideshow.Compact(), null, 
      new { id = Settings.Base32Regex } 
     ); 

     routes.MapRoute(
      "FlexibleSlideshow", 
      "x{id}", 
      MVC.Slideshow.Flexible(), null, 
      new { id = Settings.Base32Regex } 
     ); 

     routes.MapRoute(
      "Html5Slideshow", 
      "h{id}", 
      MVC.Slideshow.NonBrandedHtml5(), null, 
      new { id = Settings.Base32Regex } 
     ); 

내가 T4MVC을 사용하고 있습니다 점에 유의해야한다 (섹션 2.2.5 참조),이 MapRoute 방법은 확장입니다 : 여기 라우팅 코드는 스크린 샷에서 RouteDebug 테이블에서 명확하지 않다 경우입니다 T4MVC에 의해 추가되었습니다. I가 사용하고있는 MapRoute 방법은 표준 방법에 해당하고, I는 동일한 결과 비 T4MVC MapRoute 방법을 사용하여 시도 : 여기

 routes.MapRoute(
      "Html5Slideshow", 
      "h{id}", 
      new { controller = "Slideshow", action = "NonBrandedHtml5" }, 
      new { id = Settings.Base32Regex } 
     ); 

I 함께이없이 시도 불구 Base32Regex이고, 제약 조건 (내가 사용하는 Base32 구현은 I와 O가 1과 0이라고 가정합니다).

public static partial class Settings 
{ 
    public static string Base32Regex 
    { 
     get { return @"[0-9ABCDEFGHJKMNPQRSTVWXYZ]+"; } 
    } 
} 
+0

게시 할 수 있습니까? Base32 Regex? – epignosisx

+0

@epignosisx : 예, 했어요. 그것은 스크린 샷에 있지만, 전체 크기로 나오지 않았습니다. Regex 제약 조건이 있든 없든 같은 결과를 얻었습니다. –

+0

@qes 경로를 위해 FireFox에서 사용하는 도구는 무엇입니까 ?? –

답변

3

글쎄, 나는 단지 경솔하다. 몇 가지 다른 테스트를 수행했으며, 볼 수있는 한, 라우트 매개 변수 앞에 동일한 상수가 반복되는 문자가있을 때 라우트를 검사하는 방식에 버그가 있어야합니다. 다른 어떤 불허 예 :

"nn{id}" 
route matches (/nna0) 
route doesn't match (/nnn0) 

"nnn{id}" 
route matches (/nnna0) 
route doesn't match (/nnnn0) 

가 최대한 빨리 같은 문자를 반복하지 상수를 만드는 등, 모든 것이 잘

"mn{id}" 
route matches (/mna0) 
route matches (/mnn0) 
route matches (/mnmn) 

이 당신이 찾고있는 정확하게하지 않을 수 있습니다. 그러나 상황의 이상한 점을 고려할 때, 그것은 내가 생각해 낼 수있는 유일한 것입니다. 제약 조건에 상수를 추가하고 URL에서 제거하십시오. 그런 다음 컨트롤러에서 (이것은 내가 좋아하지 않는 부분입니다) id 매개 변수에서 해당 상수를 제거해야합니다. 희망이 작동하거나, 적어도 다른 해결책을 촉발 도움이됩니다.

routes.MapRoute(
    "NonBrandedSlideshow", 
    "{id}", 
    MVC.Slideshow.NonBranded(), null, 
    new { id = "n"+Settings.Base32Regex } 
); 

UPDATE :

나는 이것이 known issue 추측, 이것은 해결 방법입니다 최대 토로

+0

흥미 롭다면, 나는 그것이 알려진 문제 였지만 그 실을 발견하지 못했다는 확인을 찾고있었습니다. '/ n8n'과 같은 URL이 작동합니다 (Haacked가'_id_'가'__id' 이외에 작동하지 않는다고 말하는 것 같습니다.) –

+0

같은 날에 나는이 질문을 게시했는데 게시 한 것과 비슷한 해결 방법을 이미 구현했기 때문에 간단하게 작동시킬 필요가있었습니다. 그러나 제약 조건에 'n'등을 추가하는 것을 생각하지 않았습니다. 대신에 그들 모두가 동일한 액션으로 이동하게하고 거기에서 파견하기 위해 첫 번째 캐릭터의 스위치를 사용했습니다 . 내가 어떻게하면 더 좋은 대답이 게시되지 않는 한 그 현상금을 당신에게 줄 것입니다. –

+0

@qes, 꽤 이상한 버그입니다. 밑줄에 대한 좋은 관찰, 나는 정말로 할 수 없습니다. 그것이 어떻게 행동하는지 꽤 이해합니다. 고마워요! – mateuscb

2

나는 "const{param}" 같은 경로 매개 변수에 상수 접두어와 일치하도록 경로를 점점 많은 성공이 없었어요. 접두사를 완전한 경로 세그먼트로 사용하려고 시도 했습니까? 예 : "const/{param}"? 그것은 귀하의 요구 사항을 충족합니까?

routes.MapRoute(

    "NonBrandedSlideshow", 
    "n/{id}", 
    MVC.Slideshow.NonBranded(), null, 
    new { id = Settings.Base32Regex } 
); 

routes.MapRoute(
    "FullSlideshow", 
    "f/{id}", 
    MVC.Slideshow.Full(), null, 
    new { id = Settings.Base32Regex } 
); 

... 등? 코멘트 후 #

업데이트는 1

을 이해했다. 시도 할 생각할 수있는 유일한 다른 방법은 id 매개 변수를 catchall 매개 변수로 만드는 것입니다. 그것이 작동하는 경우를 참조하십시오 :

routes.MapRoute(

    "NonBrandedSlideshow", 
    "n{*id}", 
    MVC.Slideshow.NonBranded(), null, 
    new { id = Settings.Base32Regex } 
); 

routes.MapRoute(
    "FullSlideshow", 
    "f{*id}", 
    MVC.Slideshow.Full(), null, 
    new { id = Settings.Base32Regex } 
); 

그러나,이 노선 늦게 등록해야, 컨트롤러가이 컨트롤러 행동 등 N, F,로 시작 어떤 URL 라우팅 끝나지 않도록.

+0

불행히도 요구 사항에 제약이 있습니다. 이 시스템은 생산 단계에 있으며 이미 널리 배포 된 슬라이드 쇼의 URL 구조를 변경하는 것은 불가능합니다. 이 경우 모든 경로를 접두어없이 하나의 경로를 사용하고 문자열을 확인하는 작업의 논리를 사용하여 동일한 컨트롤러 동작으로 회피하여 해결 방법을 구현할 수 있어야합니다. 그러나 라우팅 수준에서 솔루션을 찾는 것이 좋습니다. –

+0

re : update - ArgumentException : "리터럴 섹션이나 매개 변수와 같은 둘 이상의 섹션을 포함하는 경로 세그먼트에 catch-all 매개 변수를 포함 할 수 없습니다." 그게 효과가없는 것처럼 보입니다. –

+0

확인. 이 문제를 해결하지 못하는 것에 대한 대답으로 답을 남겨 둘 것입니다. 행운을 빕니다. – danludwig

1

끝에 경로 제한없이 일치시켜 보았습니까?

편집 : 반 답변 죄송합니다 당신이 떨어져 첫 번째 문자를 제거 경로 제약

 routes.MapRoute(
      "NSlideshow", 
      "{id}", 
      new { controller = "SlideShow", action = "N", id = UrlParameter.Optional }, 
      new 
      { 
       id = @"^[n]{1}[0-9ABCDEFGHJKMNPQRSTVWXYZ]+" 
      } 
     ); 

    routes.MapRoute(
      "GSlideshow", 
      "{id}", 
      new { controller = "SlideShow", action = "G", id = UrlParameter.Optional }, 
      new 
      { 
       id = @"^[g]{1}[0-9ABCDEFGHJKMNPQRSTVWXYZ]+" 
      } 
     ); 

헹굼이 시도하고 액션 메소드에서, 각각의 경우에 대해 반복해야

을 중단있어 id의 앞

+0

나는 시도했지만, 그들은 일치하지 않는다. (아마도이 ​​질문은 대답보다 더 적절할 것입니다.) –

3

이것은 ASP.NET 라우팅의 알려진 버그입니다. 설명 및 해결 방법은 this answer을 참조하십시오. 즉, 리터럴 하위 세그먼트를 사용하는 것이 효과가 없습니다.

1

@ 감사합니다. 이상한 것, 내 생각 엔 ...

라우팅 규칙은 매우 간단하므로 사용자 정의 ControllerFactory을 만들고 URL을 확인할 수 있습니다. url이 사용자의 방식과 일치하면 사용할 컨트롤러와 작업을 정의하고 url을 기반으로 id 매개 변수를 설정할 수 있습니다. 그렇지 않으면 규칙적인 행동을 그대로 두십시오.

알고 계시 겠지만, 기본 라우팅을 사용하지는 않겠지 만 작동하지 않으므로 좋은 소식은 해결되면 바로 경로를 업데이트하고 사용자 정의 ControllerFactory를 제거하고 해결 방법없이 계속하십시오.

관련 문제