2008-10-25 4 views
16

방문자가 자신의 URL을 구성하고 원하는 것으로 ID를 대체하는 가장 좋은 방법은 무엇입니까? 예를 들어ASP.Net MVC - 잘못된 URL 매개 변수 처리

:

ASP.Net MVC - handling bad URL parameters

그러나 사용자가 그냥 간단하게로 URL을 대체 할 수있는 :

https://stackoverflow.com/questions/foo

내가 모든 컨트롤러 기능 매개 변수 String을 생각했습니다, 그 (것)들에 Integer.TryParse()를 사용하십시오 - 저것이 통과하는 경우에 나는 ID가 있고 계속할 수있다, 그렇지 않으면 나는 Unknown/not-found 또는 색인 전망에 사용자를 방향을 바꿀 수있다.

스택 오버플로를 잘 처리하고 싶습니다. 어떻게 수행합니까? 또는 무엇을 제안 하시겠습니까?

답변

12

여기 수에 대한 제약과 함께, 당신과 같은 경로의 예 :

routes.MapRoute(
    "Question", 
    "questions/{questionID}", 
    new { controller = "StackOverflow", action = "Question" }, 
    new { questionID = @"\d+" } //Regex constraint specifying that it must be a number. 
); 

는 여기에서 우리는 questionID 적어도 하나 개의 번호로 설정. 이것은 또한 정수 이외의 어떤 것도 포함하고있는 모든 URL을 차단할 것이고 nullable int가 필요하지 않게 할 수도 있습니다.

참고 : 여기에는 Int32 (-2147483647 - +2147483647) 범위보다 큰 숫자는 고려되지 않습니다. 나는 이것을 해결할 사용자에게 연습 문제로 남겨 둡니다. :)

사용자가 "questions/foo"라는 URL을 입력하면 매개 변수 제약 조건을 충족시키지 못하기 때문에 Question 동작을 수행하지 않고 넘어갑니다. 당신은 더 아래로 캐치 올/기본 경로에서 원하는 경우를 처리 할 수 ​​

routes.MapRoute(
    "Catchall", 
    "{*catchall}", // This is a wildcard routes 
    new { controller = "Home", action = "Lost" } 
); 

이 홈 컨트롤러에서 잃어버린 조치로 사용자를 보낼 것입니다. 와일드 카드에 대한 자세한 내용은 here을 참조하십시오.

NB : Catchall은 마지막 경로로 있어야합니다. 체인을 위로 올려 놓으면 ASP.NET MVC에서 느린 경로의 라우팅을 고려할 때 체인 아래에 다른 모든 핸들을 처리한다는 의미입니다.

+2

이것은 미친 사용자를 처리하는 꽤 좋은 방법처럼 보입니다.) – JOBG

+2

Scott Hanselman은 마지막 줄 대신 'new {questionID = @ "\ d {1,}"}' questionID = @ "\ d +"} '같은 것을 의미합니다. 출처 : http://www.asp.net/learn/mvc-videos/video-7093.aspx – Andrew

+1

네, 둘은 거의 똑같습니다. 데이터베이스에서 내 경로를 동적으로 생성하기 때문에 중괄호로 중괄호를 쓰는 경향이 있습니다. 최대 자릿수를 명시 적으로 지정하려면 논리가 약간 저장됩니다. –

0

이러한 접근법의 문제점은 여전히 ​​페이지에 매핑되지 않는 정수를 전달할 수 있다는 것입니다. "foo"를 사용하는 것처럼, 그렇게하면 404를 반환하십시오. 명확한 보안상의 영향이 없다면 걱정할 부분이 아닙니다.

+0

확실히, Integer가 유효한지 확인해야하지만 Function 매개 변수 유형으로 String을 사용하고 있습니까? - TaskList 예제 (http://www.asp.net/learn/mvc/tutorial-01-cs.aspx ~ 35min 43s)는 ID를 Integer에 강력하게 입력하므로 'foo'가 전달되면 오류가 발생합니다. o/ – Andrew

3

ASP.NET MVC에서 IActionFilter 인터페이스를 구현하는 필터를 정의 할 수 있습니다. 이 속성을 사용하여 작업을 꾸밀 수 있으므로 작업 전이나 작업 후에 실행될 수 있습니다.

귀하의 경우, 귀하의 조치 전에 "실행"되도록 귀하가 정의하게됩니다. 따라서 전달 된 매개 변수에 오류가 있으면 취소 할 수 있습니다. 여기에서 전달 된 매개 변수를 한 번만 확인 (즉, 필터에서 정의)하는 코드를 작성하고 컨트롤러 작업에서 원하는 곳 어디에서나 사용할 수있는 주요 이점이 있습니다.

MVC 여기에 필터에 대한 자세한 내용 : http://haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx

2

당신은 정규 표현식으로 제약 조건을 지정하거나 사용자 정의 제약 조건을 정의 할 수 있습니다. 자세한 내용은이 블로그 게시물에서보세요 :

http://weblogs.asp.net/stephenwalther/archive/2008/08/06/asp-net-mvc-tip-30-create-custom-route-constraints.aspx

하는 당신은 여전히 ​​아이디 43243은 IActionFilter 또는 컨트롤러에서 처리 할 수있는 아무것도에 매핑되지 않는 상황에 대처해야합니다 직접.

5

다음은 유용한 정보입니다. 당신이

public ActionResult Edit(int? id) 
{} 

다음 액션 메소드가있는 경우

/Home/Edit/23 

에있는 사람의 유형은 매개 변수 ID는

/Home/Edit/Junk 

다음 ID가 될 것입니다에 23 그러나 만약 누군가 유형 될 경우 꽤 괜찮은 null입니다. 나는 캐스팅 오류 또는 뭔가를 던질 것이라고 생각. 즉, id가 null 값이 아니라면 유효한 정수이며 DB 상호 작용을 위해 서비스 등에 전달 될 수 있습니다.

희망 사항은 테스트 중에 발견 한 정보를 제공합니다.

+0

또한 ModelState에는 매개 변수 "id"의 문제를 반영하는 모델 오류가 있습니다. –