도트 문자 '.' MVC Web API 2에서 api / people / STAFF.45287과 같은 요청


106

내가 작동하도록하려는 URL은 http://somedomain.com/api/people/staff.33311 스타일 중 하나입니다 (LAST.FM과 같은 사이트는 RESTFul 및 웹 페이지 URL에 모든 종류의 표시를 허용하는 것과 같습니다). 예를 들어 " http://www.last.fm/artist/psy'aviah "는 LAST.FM의 유효한 URL입니다.)

작동하는 시나리오는 다음과 같습니다.- http : //somedomain.com/api/people/-모든 사람을 반환합니다.- http ://somedomain.com/api/people/staff33311-도 작동하지만 내가 아닙니다. m 다음과 같이 URL에 "점"이 허용되기를 원합니다 ( http://somedomain.com/api/people/staff.33311) .

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

다음을 설정했습니다.

  1. 컨트롤러 "PeopleController"

    public IEnumerable<Person> GetAllPeople()
    {
        return _people;
    }
    
    public IHttpActionResult GetPerson(string id)
    {
        var person = _people.FirstOrDefault(p => p.Id.ToLower().Equals(id.ToLower()));
        if (person == null)
            return NotFound();
    
        return Ok(person);
    }    
    
  2. WebApiConfig.cs

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
    
        // Web API routes
        config.MapHttpAttributeRoutes();
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
    

나는 이미이 블로그 포스트 http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx 의 모든 팁을 따르려고 시도 했지만 여전히 작동하지 않습니다. 더 좋고 안전한 방법입니다.

우리는 내부적으로 이와 같은 ID를 가지고 있으므로 점을 어떤 식 으로든, 가급적이면 "."스타일로 맞추기위한 해결책을 찾아야합니다. 하지만 필요한 경우 URL에 대한 대체 제안에 열려 있습니다.


10
대답은 아니지만 somedomain.com/api/people/staff.33311에 대해 404가 표시되는 이유 에 대해서는 기본적으로 IIS가이 URL을보고. 파일 확장자로 지정하고 MVC API를 우회하여 정적 파일 핸들러를 호출합니다. 당신은 (그러므로 당신의 컨트롤러)를 ASP.NET 파이프 라인을 통해 이동하는 IIS에 모든 요청을 강제하기 때문에 대답 당신이 (모든 요청에 대해 모든 관리 모듈을 실행) 가능 작동
헨리 C

여기에 밀접하게 관련된 게시물 입니다.
RBT

답변:


104

web.config파일 에서 다음 설정을 사용 하면 문제가 해결됩니다.

<configuration>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />

4
트릭을했습니다. 하지만이 옵션을 설정하면 취약점이 있습니까? 이것이 표준 동작이 아닌 이유는 무엇입니까?
Yves Schelpe 2014 년

2
좋아, 사람의 관심을 : 참조하십시오 (카필 김시연 의해 답변) 글을 쓰는 시점에서 허용 대답 여기에 대답하고 위 내 질문 : stackoverflow.com/questions/11048863/...
이브 Schelpe

2
예, 작동했습니다. 다른 사람을 버스로 이동합니다.이 기능이 작동하는 데 어떤 특정 모듈이 필요한지 알고 싶습니다.
Greg Z.

3
이것을 시도했을 때 경로 끝에 '/'를 입력하면 작동합니다. 그 이유는 무엇입니까? 참고로 모든 모듈을 실행하는 대신 'UrlRoutingModule'을 구체적으로 추가하는 아래 답변도 저에게 효과적이지만 작동하려면 끝에 '/'가 필요하다는 문제가 있습니다.
Nikolaj Dam Larsen

10
runAllManagedModulesForAllRequests 활성화가 성능에 미치는 영향에 대해 염려한다면 stackoverflow.com/a/12151501/167018 을 살펴볼 가치가 있습니다.
Henry C

140

예를 들어 http://somedomain.com/api/people/staff.33311/대신 슬래시로 URL을 추가합니다 http://somedomain.com/api/people/staff.33311.


3
@AgustinMeriles 내 대답은 실제 대답보다 해결 방법으로 간주 될 수 있으며 질문에 대한 해석에 따라 다릅니다.
Danny Varod

5
하지만 / people / member에서와 같이 URL 섹션의 끝에 점이 있으면 작동하지 않습니다.
eYe

2
아니요, 마지막에 슬래시를 원하지 않으면 어떻게해야합니까?! 필수 는 아닙니다 .
Josh M.

1
@JoshM. 이것은 해결 방법이며 ASP.NET을 작성하지 않았습니다. 또한 슬래시는 요청에 영향을주지 않습니다. 그러나에서 google.com/my query goes here/와 같이 의도를 더 명확하게하는 데 도움이됩니다 google.com/subDomain my query goes here.
Danny Varod

1
예, web.config를 수정하지 않아도되는 것이 최선입니다.
Timothy Gonzalez

35

표준 전에 다음 을 추가 하면 문제가 해결 된다는 것을 알았 습니다.ExtensionlessUrlHandler

<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
     path="api/*"
     verb="*"
     type="System.Web.Handlers.TransferRequestHandler"
     preCondition="integratedMode,runtimeVersionv4.0" />

IDE (제 경우에는 Visual Studio)가 사이트 구성을 관리하는 경우 도움이된다는 점을 제외하면 이름이 실제로 그다지 중요하지 않다고 생각합니다.

H / T에서 https://stackoverflow.com/a/15802305/264628


나는 그것을 표준 라인 '뒤에'추가했고 잘 작동했습니다.
Jalal El-Shaer

이것은 받아 들여진 대답이어야합니다. 필요하지 않음 / uri 끝에
daudihus

2
BEFORE가 나중에 작동하지 않았기 때문에 감사합니다!
Mese

나는 모듈이 선언 순서대로 실행한다고 믿으므로 항상 더 일반적인 것보다 더 구체적이거나 더 중요한 것을 두십시오.
BrianS

24

나는 내가 실제로 무엇을하고 있는지 모르겠지만 이전 답변을 조금 사용한 후에 다른 아마도 더 적절한 해결책을 찾았습니다.

<system.webServer>
<modules>
    <remove name="UrlRoutingModule-4.0" />
    <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>

고마워, 나는 그것이 무엇을하는지 모르겠지만 다른 솔루션보다 좋아 보인다.
Thomas

1
url 라우팅 모듈 (요청에 확장자가 포함 된 것을 포착 한 다음 파일로 처리하려고 시도하는 것)을 모듈 목록의 끝으로 이동하는 것으로 보이며, 이는 API 요청을 처리하는 모듈 뒤에 배치하기에 충분합니다. . IMHO,이 적어도 내가 SO에서 본 것들에서 사용할 수있는 가장 좋은 해결 방법이다 ATTOW는
제임스 매닝

1
목록 끝으로의 재배치가 아니라이 모듈이 관리되는 처리기에 대해서만 실행되는 기본 전제 조건을 제거하는 것입니다. 기본 구성은 다음 형식을 사용합니다.<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler" />
theta-fish

고마워요-그게 그 행동을 설명 할 것입니다.
Greg Z.

8

runAllManagedModulesForAllRequests속성을로 설정하는 것 이상의 작업이 필요하다는 것을 알았 습니다 true. 또한 확장없는 URL 처리기가 모든 경로를 보도록 구성되었는지 확인해야했습니다. 또한 추가 할 수있는 추가 구성 설정이 하나 더 있습니다. 이는 경우에 따라 도움이됩니다. 내 작업 Web.config는 다음과 같습니다.

<system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true" />
</system.web>
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
        <remove name="WebDAV" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0"  path="*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

특히 ExtensionlessUrlHandler-Integrated-4.0path속성 은 (예를 들어) *와 반대로 설정되어 *.있습니다.


나는 방금 path="*.". 궁금한 점은 사람들이 설정 한 이유가 무엇 path="*."입니까?
JustinP8

실제로 path="*"WebAPI와 함께 문서 사이트를 호스팅하고 있고 해당 사이트에 .jpg, .png 및 기타 확장자가있는 파일에 문제가 있었기 때문에로 변경 하고 문제가 발생했습니다.
JustinP8

@ JustinP8 당신도 설정 했습니까 <modules runAllManagedModulesForAllRequests="true" />? 그러면 .NET이 이러한 정적 파일을 처리하게됩니다.
Josh M.

1
예. 나는 그렇게했다. 지금은 모든 정적 파일이 .NET 파이프 라인을 통과하기 때문에 정말 마음에 들지 않습니다. 다행히 이것은 webAPI 서비스이므로 API 문서 / 도우미 사이트에 대한 Swagger 및 Swashbuckle 항목 만 영향을받습니다.
JustinP8

나는 이것이 모든 정적 파일 요청을 깨뜨리는 것을 발견했습니다. 오류 500. runAllManaged ...가 true로 설정되었습니다.
Sam

2

나는이 상황에 갇혀 있었지만 / URL 끝에 추가 하는 것이 깨끗해 보이지 않았습니다.

따라서 web.config handlers 태그 에 아래에 추가하기 만하면 됩니다.

<add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />

Nancy가 무엇이며 프로젝트에 포함될 도서관인지 설명해 주시겠습니까? 감사!
푸른 빛을 띤 '

1

두 가지 방법 모두 나를 위해 작동한다는 것을 알았습니다. runAllManagedModulesForAllRequests를 true로 설정하거나 ExtentionlessUrlHandler를 다음과 같이 추가하십시오. 마지막으로 runAllManagedModulesForAllRequests가 사이트에 성능 영향을 미치기 때문에 extensionUrLHandler를 추가하기로 선택합니다.

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <remove name="WebDAV" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" 
       type="System.Web.Handlers.TransferRequestHandler" 
       preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

1

Web.config 파일에서 이것을 사용합니다.

<add name="ManagedSpecialNames" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

표준 "ExtensionlessUrlHandler"이전에.

예를 들어 제 경우에는 여기에 넣었습니다.

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ManagedFiles" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

따라서 애플리케이션 디렉토리 트리의 파일로 표준 관리하는 대신 이러한 패턴의 URL을 사용자가 관리하도록 강제합니다.


0

나는 똑같은 문제와 IIS 및 웹 사이트 구성 관련 설정으로 플레이해서는 안되는 상황에 직면했습니다. 그래서 코드 수준에서만 변경하여 작동하도록해야했습니다.

간단한 요점은 URL에 점 문자가있는 가장 일반적인 경우는 사용자로부터 입력을 받고이를 쿼리 문자열 또는 URL 조각으로 전달하여 작업 메서드의 매개 변수에 일부 인수를 전달할 때입니다. 컨트롤러의.

public class GetuserdetailsbyuseridController : ApiController
{
     string getuserdetailsbyuserid(string userId)
     {
        //some code to get user details
     }
}

사용자가 개인 정보를 얻기 위해 사용자 ID를 입력하는 아래 URL을 살펴보십시오.

http://mywebsite:8080/getuserdetailsbyuserid/foo.bar

서버에서 데이터를 가져와야하므로 http GET동사를 사용 합니다. GET호출을 사용하는 동안 모든 입력 매개 변수는 URL 조각에서만 전달할 수 있습니다.

그래서 내 문제를 해결하기 위해 내 행동의 http 동사를 POST. Http POST동사에는 사용자 또는 비 사용자 입력을 본문에 전달하는 기능도 있습니다. 그래서 JSON 데이터를 생성하여 http POST요청 본문에 전달했습니다 .

{
  "userid" : "foo.bar"
}

아래와 같이 메소드 정의를 변경하십시오.

public class GetuserdetailsbyuseridController : ApiController
{
     [Post]
     string getuserdetailsbyuserid([FromBody] string userId)
     {
        //some code to get user details
     }
}

참고 : 사용하는 경우에 대한 자세한 GET동사 때 사용하는 POST동사 여기 .


REST API를 빌드하는 경우 적절한 솔루션이 아닙니다.
Mustafa Ozturk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.