URL의 점으로 인해 ASP.NET mvc 및 IIS에서 404가 발생 함


303

내 URL에 경로가 필요한 프로젝트가 있습니다. 예를 들어 www.example.com/people/michael.phelps와 같은 URL이있을 수 있습니다.

점이있는 URL은 404를 생성합니다. 내 라우팅은 괜찮습니다. 점없이 michaelphelps를 전달하면 모든 것이 작동합니다. 점을 추가하면 404 오류가 발생합니다. 샘플 사이트는 IIS8 Express가 설치된 Windows 7에서 실행됩니다. URLScan이 실행되고 있지 않습니다.

web.config에 다음을 추가하려고했습니다.

<security>
  <requestFiltering allowDoubleEscaping="true"/>
</security>

불행히도 그것은 차이가 없었습니다. 404.0 Not Found 오류가 나타납니다.

이것은 MVC4 프로젝트이지만 관련이 있다고 생각하지 않습니다. 내 라우팅이 제대로 작동하고 도트가 포함될 때까지 내가 기대하는 매개 변수가 있습니다.

URL에 점을 표시하려면 무엇을 구성해야합니까?


93
내가 이것에 많은 시간을 보냈다는 것을 믿을 수 없다. 후행 슬래시를 추가하면 URL이 제대로 작동합니다. 예를 들어 www.example.com/people/michael.phelps/ 그러나 슬래시 IIS가 없으면 404 오류가 발생합니다.
Mark

15
Mark-마지막 슬래시가 없으면 IIS는 해당 파일이 찾아야하는 파일이라고 생각하기 때문입니다. 슬래시를 추가하면 효과가 있습니다. 이것은 실제 파일이 아닙니다. 또한 아래의 구성 옵션은 IIS가 파일이 아닌 경우 대신 라우팅하도록 시도합니다.
Tommy

프로젝트를 mvc 4 + asp.net 4.5로 업데이트 한 후에도 같은 문제가 발생합니다.
Tadeu Maia

해결 방법으로 IIS Rewrite를 사용하여 URL에 후행 슬래시를 추가합니다.
Mark

4
이것은 나를 위해 작동하지 않습니다. URL은 "."와 잘 작동합니다. URL 내에 있지만 끝에있을 때 오류가 발생합니다
Arcadian

답변:


379

내 사이트의 HTTP 처리기를 편집 하여이 작업을 수행했습니다. 내 필요에 따라 이것은 잘 작동하고 내 문제를 해결합니다.

특정 경로 기준을 찾는 새로운 HTTP 처리기를 추가했습니다. 요청이 일치하면 처리를 위해 .NET으로 올바르게 전송됩니다. URLRewrite가 해킹하거나 RAMMFAR을 활성화하는이 솔루션에 훨씬 만족합니다.

예를 들어 .NET에서 URL www.example.com/people/michael.phelps를 처리 하려면 system.webServer / handlers요소 내의 사이트 web.config에 다음 행을 추가하십시오 .

<add name="ApiURIs-ISAPI-Integrated-4.0"
     path="/people/*"
     verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
     type="System.Web.Handlers.TransferRequestHandler"
     preCondition="integratedMode,runtimeVersionv4.0" />

편집하다

이 문제에 대한 해결책이 RAMMFAR또는 임을 제안하는 다른 게시물이 RunAllManagedModulesForAllRequests있습니다. 이 옵션을 활성화하면 모든 요청에 ​​대해 모든 관리 모듈이 활성화됩니다. 즉, 이미지, PDF 및 기타 모든 파일과 같은 정적 파일은 필요하지 않을 때 .NET에서 처리됩니다. 특별한 경우가 없으면이 옵션을 사용하지 않는 것이 가장 좋습니다.


3
여기 에이 답변에 기반한 stackoverflow.com/a/16607685/801189 의 완전한 예가 있습니다.
VB

10
.css와 같은 정적 파일에 대한 모든 요청을 [path = "*"]와 함께 추가하면 .js가 실패합니다. 이 " domain / ABCDE.FGHIJ " 와 같은 URL을 처리하는 사용자 지정 경로가 있습니다. 모든 정적 파일은 / Content 디렉토리에 있습니다. 이 전체 디렉토리를 제외시키는 방법이 있습니까? RAMMFAR를 true로 설정하면 작동하지만 오버 헤드를 피하고 싶습니다.
lamarant 2016 년

2
로컬 IIS는 슬래시 시작과 함께 작동하지만 IIS8은 첫 번째 슬래시없이 경로 만 이해합니다.
Pavel Voronin

2
@lamarant와 동일한 문제가 있습니다 ... 정적 파일을 차단합니다. 왜 그런지 아십니까? 여기 MVC4를 사용하십시오.
eestein

3
MVC5에서 작동하지만 경로의 시작 부분에 슬래시를 넣으면 경로가 호스트 이름 바로 뒤에있을 때만 작동합니다 (앱 폴더와 관련이 없음). 예를 들어 경로 / people / *는 www.example.com/people/michael.phelps에서는 작동하지만 www.example.com/app/people/michael.phelps에서는 작동하지 않습니다. AFAIK는 앱을 기준으로 경로를 만들 수있는 방법이 없습니다.
Hogan

46

주위를 파고 든 후 relaxUrlToFileSystemMapping이 전혀 작동하지 않는다는 것을 알았습니다. 내 경우에는 RAMMFAR를 true로 설정하고 (.net 4.0 + mvc3) 및 (.net 4.5 + mvc4)에도 유효합니다.

<system.webserver>
    <modules runAllManagedModulesForAllRequests="true">

RAMMFAR 및 성능에 대한 RAMMFAR True Hanselman 게시물을 설정할 때주의하십시오


5
... RAMMFAR를 설정할 때 내가이 사용하는 경우 어떤 성능 손실은 <모듈 runAllManagedModulesForAllRequests을 = "진정한"> 거기주의
단도 Paudel

1
원래 포스터의 경우 IIS7 이상을 사용하므로 필요하지 않습니다. 이것이 기본값이며 RAMMFAR를 설정하면 실제로 비용이 많이 듭니다. msdn.microsoft.com/en-us/library/…를
Richard

이것이 유용하지만, 이것은 나를 위해 MVC5 / IIS7에서 404를 반환하는 것을 중단하기에 충분하지 않았습니다.
Chris Moschini

이 옵션을 사용하지 않으려면
Strake

그러나 가능하면 라이브 사이트에서이 작업을 수행하지 마십시오.
NickG

27

web.config에서 relaxUrlToFileSystemMapping 속성을 설정해야한다고 생각합니다. Haack 은 얼마 전에 이것에 관한 기사를 썼습니다 (그리고 같은 유형의 질문을하는 다른 SO 게시물이 있습니다)

<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true" />

편집 아래 설명에서 .NET / IIS의 이후 버전에서는이 system.WebServer요소 가 필요합니다 .

<system.webServer>
<httpRuntime relaxedUrlToFileSystemMapping="true" />

2
이것은 내가 mvc3 + .net4.0에서 가지고 있었고 아름답게 작동했지만 더 이상 mvc4 + .net4.5에서는 작동하지 않습니다.
Tadeu Maia

4
relaxUrlToFileSystemMapping을 성공하지 않고 시도했습니다. 최신 버전의 MVC에서는 작동하지 않는다고 생각합니다.
Mark

이렇게하면 URL /WEB-INF./web.xml을 잡아서 시도한 다른 많은 방법이 작동하지 않을 때 사용자 정의 오류 페이지로 리디렉션 할 수있었습니다.
quentin-starin

3
흥미 롭군 그것이 당신에게 효과가 없다는 것을 감안할 때, 나는 이것이 .NET4.5와 MVC4에 있다고 생각할 때 이것이 나에게 효과가 없을 것이라고 가정하려고했습니다. 그러나 빙고는 어쨌든 효과가있었습니다. 제 경우에는 단순히 "."마침표가있는 URL이있었습니다 마지막 문자로. 나는 404를 얻었지만이 문제를 해결했습니다.
PandaWood

그의 보안 영향이 있습니까?
Paesano2000

23

나는 다른 모든 구제 조치를 취하지 않고 오랫동안이 문제에 갇혔습니다.

점 [.]이 포함 된 URL 끝에 슬래시 [/]를 추가 할 때 404 오류가 발생하지 않았으며 실제로 작동했습니다.

마지막으로 IIS URL Rewrite와 같은 URL Rewriter를 사용하여 특정 패턴을 관찰하고 훈련 슬래시를 추가하여 문제를 해결했습니다.

내 URL은 다음과 같습니다. /Contact/~firstname.lastname 내 패턴은 다음과 같습니다. /Contact/~(.*[^/])$

Scott Forsyth 에서이 아이디어를 얻었습니다. 아래 링크를 참조하십시오 : http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path


이것은 나를 위해 일했습니다 (MVC5). 위의 다른 제안은 효과가 없었으며 필요하지 않았습니다. @ jonduncan05가 제안한대로 경로를 변경 하겠습니다 .
markau

고마워요, 레온 나를 위해 날을 구했다. 사람들이 여기에서 이야기하는 모든 web.config 물건에 대해 확실하지 않지만 후행 /을 추가하면 내가 필요한 대답이었습니다. 필자의 경우 서버 측 컨트롤러와 그것을 호출 한 자바 스크립트를 제어 할 수 있었으므로 JavaScript와 voila를 업데이트했습니다!
개구리 Pr1nce

21

이 섹션을 Web.config에 추가하면 pathInfo에 점이있는 경우에도 route / {* pathInfo}에 대한 모든 요청이 지정된 핸들러에 의해 처리됩니다. (ServiceStack MVC 호스트 Web.config 예제 및 https://stackoverflow.com/a/12151501/801189 에서 가져옴 )

이것은 IIS 6과 7 모두에서 작동해야합니다. 'add'요소에서 path = "*"를 수정하여 'route'다음에 다른 핸들러에 특정 핸들러를 지정할 수 있습니다.

  <location path="route">
    <system.web>
      <httpHandlers>
        <add path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" />
      </httpHandlers>
    </system.web>
    <!-- Required for IIS 7.0 -->
    <system.webServer>
      <modules runAllManagedModulesForAllRequests="true" />
      <validation validateIntegratedModeConfiguration="false" />
      <handlers>
        <add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />
      </handlers>
    </system.webServer>
  </location>

2
RAMMFAR (runAllManagedModulesForAllRequests)의 성능 결과에주의하십시오. 이렇게하면 모든 요청에 ​​대해 모든 관리되는 모듈이 활성화됩니다. 이미지와 같은 정적 파일은 IIS에서 직접 처리 할 수 ​​있지만 모든 요청에 ​​대한 오버 헤드를 추가하는 모든 모듈을 통해 파일을 처리합니다.
Mark

@점수. 예,하지만 <location> 섹션을 사용하고 기본 <system.webServer> 섹션에서 runAllManagedModulesForAllRequests를 설정하지 않으면 라우팅 / ... 요청에만 영향을 미칩니다.
VB

@VB .NET이 처리 해야하는 URL과 일치하는 파일이 시스템에없는 한 핸들러 만 있으면 충분하다고 생각합니다. 그리고 어떤 이유로 RAMMFAR은 <location> 수준에서 작동하지 않았지만 처리기 솔루션은 작동했습니다.
webXL

MVC가 지정된 경로에 대한 요청을 처리하고 경로를 추가하지 못하게하려면 @webXL <location>이 필요합니다 .IgnoreRoute ( "route / {* pathInfo}"); 그러면 IIS는 <location path = "route"> 위치 섹션을 살펴보고 위치 섹션에서 지정된 처리기를 사용하지만 MVC의 라우팅 및 기타 MVC의 파이프 라인 단계를 완전히 무시합니다. 내 프로젝트에서 ServiceStack API는 해당 설정이 없으면 작동하지 않습니다.
VB

왜 단순히 핸들러를 추가하지 않는가? 내 경우에는 처리기와 함께 RAMMFAR을 추가해야합니다. 여기에 좋은 설명이 있습니다. :)
Aditya Patil

6

MVC 5.0 해결 방법.

제안 된 답변 중 많은 부분이 MVC 5.0에서 작동하지 않는 것 같습니다.

마지막 섹션의 404 도트 문제는 슬래시로 해당 섹션을 닫아 해결할 수 있으므로 여기에 내가 사용하는 깔끔하고 간단한 작은 트릭이 있습니다.

편리한 자리 표시자를 유지하면서 :

@Html.ActionLink("Change your Town", "Manage", "GeoData", new { id = User.Identity.Name }, null)

작은 jquery / javascript를 추가하여 작업을 완료하십시오.

<script>
    $('a:contains("Change your Town")').on("click", function (event) {
        event.preventDefault();
        window.location.href = '@Url.Action("Manage", "GeoData", new { id = User.Identity.Name })' + "/";
    });</script>

후행 슬래시에 유의하십시오.

http://localhost:51003/GeoData/Manage/user@foo.com

으로

http://localhost:51003/GeoData/Manage/user@foo.com/

5

하나의 웹 페이지에만있는 사람들에게는 매우 쉬운 답변입니다. 작업 링크와 그 끝에있는 + "/"를 편집하십시오.

  @Html.ActionLink("Edit", "Edit", new { id = item.name + "/" }) |

나를 위해 해결했습니다! 간단하고 우아한! 개발 과정에서 Windows 10에서 '/'없이 작동한다는 것이 가장 큰 자극이지만 Windows 2012의 경우에는 필요한 것 같습니다.
Wim ten Brink

2

마침표 대신 대시를 사용하는 것이 좋습니다.

Pro ASP MVC 3 Framework 에서는 친숙한 URL을 만드는 방법에 대해 다음과 같이 제안합니다.

기호, 코드 및 문자 시퀀스를 피하십시오. 단어 구분 기호를 원하면 대시 (/ my-great-article)를 사용하십시오. 밑줄은 친숙하지 않으며 URL 인코딩 된 공간은 기괴하거나 (/ my + great + article) 또는 역겨운 (/ my % 20great % 20article)입니다.

또한 URL은 사람이 쉽게 읽고 변경할 수 있어야한다고 언급합니다. 점 대신 대시를 사용하는 것에 대한 생각이 같은 책에서 비롯된 것일 수도 있습니다.

HTML 페이지 (.aspx 또는 .mvc)에는 파일 이름 확장자를 사용하지 말고 특수한 파일 형식 (.jpg, .pdf, .zip 등)에는 사용하십시오. MIME 유형을 적절하게 설정하면 웹 브라우저는 파일 이름 확장자를 신경 쓰지 않지만 사람은 여전히 ​​PDF 파일이 .pdf로 끝나기를 기대합니다.

따라서 마침표는 여전히 사람이 읽을 수 있지만 (대시, IMO보다 읽기 쉽지는 않지만) 마침표 뒤에 나오는 내용에 따라 약간 혼란스럽고 오도 할 수 있습니다. 성이 zip 인 사람은 어떻게합니까? 그러면 URL은 / John-zip 대신 /John.zip이되며 응용 프로그램을 작성한 개발자에게도 오해의 소지가 있습니다.


본질적으로 점이 포함 된 사용자 이름 또는 기타 필드 일 수 있습니다. 즉, StackOverflow는를 포함하여 모든 구두점을 .사용자 URL에서 대시로 바꿉니다 . : P
jli

route 매개 변수에 파일 이름을 포함하는 안전한 파일 검색 서비스가 있기 때문에이 문제가 발생했습니다.
FlavorScape

명백한 이유에 대한 공감 : 그것은 질문에 대답하지 않습니다. 가능한 경우 URL에 마침표가 표시되지 않도록합니다. URL이 생성되고 사람이 읽을 수 있어야하기 때문에 나타납니다.
mg30rg

2

쿼리 문자열없이 URI를 유지하는 것이 얼마나 중요한지에 따라 URI가 아닌 쿼리 문자열의 일부로 점으로 값을 전달할 수도 있습니다.

예를 들어 www.example.com/people?name=michael.phelps는 설정이나 아무것도 변경하지 않고도 작동합니다.

깔끔한 URI를 갖는 우아함을 잃어 버리지만이 솔루션에는 설정이나 핸들러를 변경하거나 추가 할 필요가 없습니다.


1

URL 구조를 변경할 수 있습니까?
내가 일하고있는 것을 위해 나는 경로를 시도했다.

url: "Download/{fileName}"

하지만 그것을 가진 어떤 것도 실패했습니다. 그 안에.

나는 경로를

    routes.MapRoute(
        name: "Download",
        url:  "{fileName}/Download",
        defaults: new { controller = "Home", action = "Download", }
    );

이제 넣을 수 localhost:xxxxx/File1.doc/Download있으며 제대로 작동합니다.

뷰의 내 도우미들도 그것을 선택했습니다.

     @Html.ActionLink("click here", "Download", new { fileName = "File1.doc"})

localhost:xxxxx/File1.doc/Download형식에 대한 링크도 만듭니다 .

당신의 재산은 후행로 종료 할 수 있도록 아마 당신은 경로의 끝에 "/보기"또는 조치와 같은 불필요한 단어를 넣을 수 /같은/mike.smith/view


1

path = "변경하는 것만 큼 간단 합니다." path = " "로 web.config에서 ExensionlessUrlHandler-Integrated-4.0의 경로에서 점을 제거하십시오.

다음은 좋은 기사입니다 https://weblog.west-wind.com/posts/2015/Nov/13/Serving-URLs-with-File-Extensions-in-an-ASPNET-MVC-Application


이 링크를 통해 문제에 대한 최상의 해결책을 찾을 수있었습니다 (세그먼트에는 "."문자가 포함되어 있지만 클라이언트는 "/"로 끝나지 않습니다). web.config의 <system.webServer>-<modules runAllManagedModulesForAllRequests = "true"/>에이 줄이 추가되어 수정되었습니다.
NickBeaugié

1

위의 모든 솔루션을 시도했지만 그중 아무것도 나를 위해 일하지 않았습니다. 작동 한 것은 모든 다국어 버전을 포함하여 .NET 버전> 4.5를 제거하는 것이 었습니다. 결국 나는 새로운 (영어로만) 버전을 하나씩 추가했습니다. 현재 내 시스템에 설치된 버전은 다음과 같습니다.

  • 2.0
  • 3.0
  • 3.5 4
  • 4.5
  • 4.5.1
  • 4.5.2
  • 4.6
  • 4.6.1

그리고 여전히이 시점에서 작동합니다. 4.6.2를 설치하는 것이 모든 것을 망칠 수 있기 때문에 설치가 두렵습니다.

따라서 4.6.2 또는 영어 이외의 모든 버전이 내 구성을 망쳐 놓고 있다고 추측 할 수있었습니다.



0

솔루션은 .base64와 같이 symbol을 포함하지 않는 형식으로 인코딩하는 것을 고려할 수도 있습니다 .

js에 추가해야합니다

btoa(parameter); 

컨트롤러에서

byte[] bytes = Convert.FromBase64String(parameter);
string parameter= Encoding.UTF8.GetString(bytes);

0

Web.config 아카이브에 URL 다시 쓰기 규칙을 추가하십시오. 당신은 가질 필요가 URL 재 작성 모듈 이 이미 IIS에 설치합니다. 다음 재 작성 규칙을 자신의 영감으로 사용하십시오.

<?xml version="1.0" encoding="utf-8"?>
<configuration>

<system.webServer>
  <rewrite>
    <rules>
      <rule name="Add trailing slash for some URLs" stopProcessing="true">
        <match url="^(.*(\.).+[^\/])$" />
          <conditions>
              <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
              <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Redirect" url="{R:1}/" />
      </rule>
    </rules>
    </rewrite>
</system.webServer>

</configuration> 

0

또한 (관련) 처리기 매핑의 순서를 확인하십시오. 그 뒤에 경로에 .svc (예 : /foo.asmx/bar.svc/path)가있는 .ashx가 있습니다. .svc 매핑은 .asmx 이전에 일치하는 .svc 경로에 대해 404였습니다. Havn은 너무 많이 생각하지 않았지만 URL을 인코딩하면 경로를 처리 할 수 ​​있습니다.


-3
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
    [RoutePrefix("File")]
    [Route("{action=index}")]
    public class FileController : Controller
    {
        // GET: File
        public ActionResult Index()
        {
            return View();
        }

        [AllowAnonymous]
        [Route("Image/{extension?}/{filename}")]
        public ActionResult Image(string extension, string filename)
        {
            var dir = Server.MapPath("/app_data/images");

            var path = Path.Combine(dir, filename+"."+ (extension!=null?    extension:"jpg"));
           // var extension = filename.Substring(0,filename.LastIndexOf("."));

            return base.File(path, "image/jpeg");
        }
    }
}

1
이것이 OP의 질문에 어떻게 대답합니까? 그것을 설명해 주시겠습니까?
kayess

해결책이 아니며 해킹이므로 파일 확장자를 uri 경로에 마침표없이 배치해야합니다 (예 : "~ / Image / jpg / cow" "/ app_data / images / cow / jpg"- -이 사람과 다른 사람들 이이 요구를 찾는 해결책이 아닙니다.
Shaun Wilson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.