Dấu chấm trong URL gây ra 404 với ASP.NET mvc và IIS


303

Tôi có một dự án yêu cầu URL của tôi có dấu chấm trong đường dẫn. Ví dụ: tôi có thể có một URL như www.example.com/people/michael.phelps

Các URL có dấu chấm tạo ra 404. Định tuyến của tôi vẫn ổn. Nếu tôi vượt qua trong michaelphelps, không có dấu chấm, thì mọi thứ đều hoạt động. Nếu tôi thêm dấu chấm, tôi gặp lỗi 404. Trang web mẫu đang chạy trên Windows 7 với IIS8 Express. URLScan không chạy.

Tôi đã thử thêm các mục sau vào web.config:

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

Thật không may, điều đó đã không tạo ra sự khác biệt. Tôi chỉ nhận được một lỗi 404.0 Không tìm thấy.

Đây là một dự án MVC4 nhưng tôi không nghĩ nó có liên quan. Định tuyến của tôi hoạt động tốt và các tham số tôi mong đợi ở đó, cho đến khi chúng bao gồm một dấu chấm.

Tôi cần gì để định cấu hình để tôi có thể có dấu chấm trong URL của mình?


93
Không thể tin rằng tôi đã dành quá nhiều thời gian cho việc này. URL hoạt động tốt nếu tôi thêm dấu gạch chéo. Ví dụ: www.example.com/people/michael.phelps/ tuy nhiên không có dấu gạch chéo IIS sẽ gây ra lỗi 404.
Đánh dấu

15
Đánh dấu - đó là bởi vì không có dấu gạch chéo, IIS nghĩ rằng đó là một tệp mà nó nên đi và tìm. Thêm dấu gạch chéo có tác dụng ... đây không phải là một tập tin thực sự. Ngoài ra, tùy chọn cấu hình bên dưới cho IIS biết rằng nếu đó không phải là tệp, hãy thử định tuyến thay thế.
Tommy

Tôi đang gặp vấn đề tương tự sau khi tôi cập nhật dự án của mình lên mvc 4 + asp.net 4.5.
Tadeu Maia

Như một công việc xung quanh tôi đang sử dụng IIS Rewrite để thêm dấu gạch chéo vào URL của tôi.
Đánh dấu

4
Điều này không làm việc cho tôi. URL hoạt động tốt với "." trong URL nhưng khi nó ở cuối, nó sẽ báo lỗi
Arcadian

Câu trả lời:


379

Tôi đã làm việc này bằng cách chỉnh sửa trình xử lý HTTP của trang web của tôi. Đối với nhu cầu của tôi, điều này hoạt động tốt và giải quyết vấn đề của tôi.

Tôi chỉ cần thêm một trình xử lý HTTP mới tìm kiếm các tiêu chí đường dẫn cụ thể. Nếu yêu cầu phù hợp, nó được gửi chính xác đến .NET để xử lý. Tôi rất vui hơn với giải pháp này là URLRewrite hack hoặc kích hoạt RAMMFAR.

Ví dụ: để .NET xử lý URL www.example.com/people/michael.phelps thêm dòng sau vào web.config trang web của bạn trong system.webServer / handlersphần tử:

<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" />

Biên tập

Có những bài viết khác cho thấy giải pháp cho vấn đề này là RAMMFARhoặc RunAllManagedModulesForAllRequests. Kích hoạt tùy chọn này sẽ cho phép tất cả các mô-đun được quản lý cho tất cả các yêu cầu. Điều đó có nghĩa là các tệp tĩnh như hình ảnh, PDF và mọi thứ khác sẽ được .NET xử lý khi chúng không cần. Tùy chọn này là tốt nhất để lại trừ khi bạn có một trường hợp cụ thể cho nó.


3
đây là một ví dụ đầy đủ stackoverflow.com/a/16607685/801189 dựa trên câu trả lời này
VB

10
sau khi thêm điều này với [path = "*"] tất cả các yêu cầu đến bất kỳ tệp tĩnh nào như .css, .js đều thất bại. Tôi có một tuyến tùy chỉnh xử lý các url trông giống như " miền / ABCDE.FGHIJ " này. Tất cả các tệp tĩnh của tôi nằm trong thư mục / Nội dung của tôi. Có cách nào để loại trừ toàn bộ thư mục này không? thiết lập RAMMFAR để hoạt động thực sự nhưng tôi muốn tránh chi phí đó.
lamarant

2
IIS cục bộ hoạt động với dấu gạch chéo bắt đầu, nhưng IIS8 chỉ hiểu lộ trình mà không có dấu gạch chéo đầu tiên.
Pavel Voronin

2
Tôi đang gặp vấn đề tương tự như @lamarant ... Nó chặn các tệp tĩnh. Bạn có biết tại sao? Sử dụng MVC4 tại đây.
eestein

3
Nó hoạt động trong MVC5, nhưng nếu bạn đặt dấu gạch chéo ở đầu đường dẫn, nó chỉ hoạt động khi đường dẫn ngay sau tên máy chủ (nó không liên quan đến thư mục ứng dụng). Ví dụ: đường dẫn / người / * sẽ hoạt động cho www.example.com/people/michael.phelps, nhưng không phải cho www.example.com/app/people/michael.phelps. AFAIK không có cách nào để tạo đường dẫn liên quan đến ứng dụng.
Hogan

46

Sau một vài lần chọc tôi thấy rằng relaxUrlToFileSystemMapping hoàn toàn không hoạt động với tôi, điều làm việc trong trường hợp của tôi là đặt RAMMFAR thành true, điều tương tự là hợp lệ cho (.net 4.0 + mvc3) và (.net 4.5 + mvc4).

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

Lưu ý khi cài đặt RAMMFAR đúng bài Hanselman về RAMMFAR và hiệu suất


5
Lưu ý khi cài đặt RAMMFAR ... Có bất kỳ mất hiệu năng nào không nếu tôi sử dụng <mô-đun run ALLManagedModulesFor ALLRequests = "true">
Shanker Paudel

1
Trong trường hợp áp phích ban đầu thì không cần thiết, vì anh ta đang sử dụng IIS7 trở lên. Đó là mặc định và cài đặt RAMMFAR thực sự khiến bạn phải trả giá. Xem msdn.microsoft.com/en-us/l Library / Mạnh
Richard

Mặc dù điều này hữu ích, nhưng điều này không đủ để có thời gian ngừng trả lại 404 trong MVC5 / IIS7 cho tôi.
Chris Moschini

Chỉ cần nhắc lại. Bạn muốn tránh bật tùy chọn này
Strake

Đừng làm điều này trên một trang web trực tiếp, nếu có thể.
NickG

27

Tôi tin rằng bạn phải đặt thuộc tính relaxUrlToFileSystemMapping trong web.config. Haack đã viết một bài báo về điều này cách đây ít lâu (và có một số bài viết SO khác hỏi cùng loại câu hỏi)

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

Chỉnh sửa Từ các bình luận bên dưới, các phiên bản .NET / IIS sau này có thể yêu cầu phần này phải nằm trong system.WebServerphần tử.

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

2
Đây là những gì tôi đã có với mvc3 + .net4.0 và hoạt động rất đẹp, nhưng không hoạt động nữa với mvc4 + .net4.5.
Tadeu Maia

4
Tôi đã thử thư giãnUrlToFileSystemMapping nhưng không thành công. Tôi không nghĩ rằng nó hoạt động với các phiên bản mới nhất của MVC.
Đánh dấu

Điều này cho phép tôi bắt được url /CHB-INF./web.xml và chuyển hướng nó đến một trang lỗi tùy chỉnh khi rất nhiều cách khác tôi đã thử không hoạt động.
quentin-starin

3
Hấp dẫn. Cho rằng nó không hiệu quả với bạn, tôi đã giả định rằng nó sẽ không hoạt động với tôi ... vì tôi đang dùng MVC4 với .NET4.5. Nhưng bingo, dù sao nó cũng hoạt động. Trong trường hợp của tôi, tôi chỉ cần có một URL có dấu "." là nhân vật cuối cùng. Tôi đã nhận được 404 nhưng điều này đã sửa nó.
PandaWood

Liệu anh ấy có hậu quả an ninh?
Paesano2000

23

Tôi đã bị mắc kẹt trong vấn đề này trong một thời gian dài theo tất cả các biện pháp khắc phục khác nhau mà không có kết quả.

Tôi nhận thấy rằng khi thêm dấu gạch chéo [/] vào cuối URL chứa dấu chấm [.], Nó không gây ra lỗi 404 và nó thực sự hoạt động.

Cuối cùng tôi đã giải quyết vấn đề bằng cách sử dụng trình ghi lại URL như IIS URL Rewrite để xem một mẫu cụ thể và nối thêm dấu gạch chéo đào tạo.

URL của tôi trông như thế này: /Contact/~firstname.lastname vì vậy mẫu của tôi chỉ đơn giản là: /Contact/~(.*[ ^ / [)

Tôi có ý tưởng này từ Scott Forsyth, xem liên kết dưới đây: http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path


Điều này làm việc cho tôi (MVC5). Các đề xuất khác ở trên không hoạt động và không cần thiết, chỉ là một dấu gạch chéo. Tôi sẽ thay đổi tuyến đường của mình theo đề xuất của @ jonduncan05 tại đây .
markau

Cảm ơn, Leon. Tiết kiệm trong ngày cho tôi. Không chắc chắn về tất cả các công cụ web.config mọi người xung quanh nói về ở đây, nhưng thêm dấu vết / là câu trả lời tôi cần. Trong trường hợp của tôi, tôi có quyền kiểm soát bộ điều khiển phía máy chủ và javascript đang gọi nó, vì vậy tôi mới cập nhật JavaScript và voila!
Ếch Pr1nce

21

Chỉ cần thêm phần này vào Web.config và tất cả các yêu cầu tới tuyến / {* pathInfo} sẽ được xử lý bởi trình xử lý đã chỉ định, ngay cả khi có các dấu chấm trong pathInfo. (lấy từ ví dụ về ServiceStack MVC Host Web.config và câu trả lời này https://stackoverflow.com/a/12151501/801189 )

Điều này sẽ hoạt động cho cả IIS 6 & 7. Bạn có thể chỉ định các trình xử lý cụ thể cho các đường dẫn khác nhau sau 'tuyến đường' bằng cách sửa đổi đường dẫn = "*" trong các phần tử 'thêm'

  <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
Cảnh giác với các hậu quả về hiệu suất chạy ALLManagedModulesFor ALLRequests (RAMMFAR) có. Điều này sẽ cho phép tất cả các mô-đun được quản lý cho mọi yêu cầu. Các tệp tĩnh, chẳng hạn như hình ảnh, có thể được xử lý trực tiếp bởi IIS nhưng điều này xử lý chúng thông qua mọi mô-đun thêm chi phí cho mọi yêu cầu.
Đánh dấu

@Điểm. có, nhưng tôi tin rằng điều này sẽ chỉ ảnh hưởng đến yêu cầu định tuyến / ... nếu chúng ta sử dụng phần <location> và không đặt phần runAllManagedModulesFor ALLRequests trong phần <system.webServer> chính.
VB

@VB Tôi nghĩ chỉ cần trình xử lý là đủ, trừ khi bạn có các tệp trên hệ thống khớp với URL mà .NET phải xử lý. Và vì một số lý do, RAMMFAR không hoạt động ở cấp độ <location>, nhưng giải pháp xử lý đã làm.
webXL

@webXL <location> cần thiết khi bạn không muốn MVC xử lý các yêu cầu đến một tuyến đã chỉ định và thêm tuyến.IgnoreRoute ("route / {* pathInfo}"); Sau đó, IIS sẽ xem xét phần vị trí <location path = "route"> và sẽ sử dụng các trình xử lý được chỉ định trong phần vị trí, nhưng nó sẽ bỏ qua hoàn toàn định tuyến của MVC và các bước đường ống khác của MVC. Trong dự án của tôi, ServiceStack api chỉ không hoạt động mà không có thiết lập đó.
VB

Tại sao đơn giản là không thêm công việc xử lý? Trong trường hợp của tôi, tôi phải thêm RAMMFAR cùng với trình xử lý. Tìm kiếm một số lời giải thích tốt ở đây. :)
Aditya Patil

6

Cách giải quyết MVC 5.0.

Nhiều câu trả lời được đề xuất dường như không hoạt động trong MVC 5.0.

Vì vấn đề chấm 404 trong phần cuối có thể được giải quyết bằng cách đóng phần đó bằng dấu gạch chéo, đây là mẹo nhỏ tôi sử dụng, sạch sẽ và đơn giản.

Trong khi giữ một giữ chỗ thuận tiện trong quan điểm của bạn:

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

thêm một chút jquery / javascript để hoàn thành công việc:

<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>

xin lưu ý dấu gạch chéo, có trách nhiệm thay đổi

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

vào

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

5

Câu trả lời siêu dễ dàng cho những người chỉ có điều này trên một trang web. Chỉnh sửa liên kết hành động của bạn và dấu + "/" ở cuối của nó.

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

Giải quyết nó cho tôi! Đơn giản và thanh lịch! Khó chịu nhất là nó hoạt động mà không có '/' trên Windows 10 trong quá trình phát triển, nhưng đối với Windows 2012 dường như là bắt buộc.
Wim ten Brink

2

Bạn có thể muốn nghĩ về việc sử dụng dấu gạch ngang thay vì dấu chấm.

Trong Pro ASP MVC 3 Framework, họ đề xuất điều này về việc tạo các URL thân thiện:

Tránh các ký hiệu, mã và chuỗi ký tự. Nếu bạn muốn phân tách từ, hãy sử dụng dấu gạch ngang (/ my-great-article). Dấu gạch dưới là không thân thiện và không gian được mã hóa URL là kỳ quái (/ my + great + bài viết) hoặc kinh tởm (/ my% 20great% 20article).

Nó cũng đề cập rằng các URL phải dễ đọc và thay đổi cho con người. Có thể một lý do để suy nghĩ về việc sử dụng dấu gạch ngang thay vì dấu chấm cũng xuất phát từ cùng một cuốn sách:

Không sử dụng phần mở rộng tên tệp cho các trang HTML (.aspx hoặc .mvc), nhưng sử dụng chúng cho các loại tệp chuyên dụng (.jpg, .pdf, .zip, v.v.). Các trình duyệt web không quan tâm đến các phần mở rộng tên tệp nếu bạn đặt loại MIME một cách thích hợp, nhưng con người vẫn mong muốn các tệp PDF kết thúc bằng .pdf

Vì vậy, trong khi một khoảng thời gian vẫn có thể đọc được cho con người (mặc dù ít đọc hơn dấu gạch ngang, IMO), nó vẫn có thể hơi khó hiểu / gây hiểu lầm tùy thuộc vào những gì xuất hiện sau khoảng thời gian đó. Nếu ai đó có họ của zip thì sao? Sau đó, URL sẽ là /John.zip thay vì / John-zip, một cái gì đó có thể gây hiểu lầm ngay cả với nhà phát triển đã viết ứng dụng.


Đó có thể là tên người dùng hoặc trường khác vốn có chứa dấu chấm. Điều đó nói rằng, StackOverflow thay thế tất cả dấu chấm câu (bao gồm .) bằng dấu gạch ngang trong các url người dùng của nó: P
jli

Tôi gặp phải điều này bởi vì tôi có dịch vụ truy xuất tệp an toàn rõ ràng có chứa tên tệp trong tham số tuyến đường ...
FlavorScape

Downvote vì lý do rõ ràng: Nó không trả lời câu hỏi. Nếu tôi có thể, tôi sẽ không để dấu chấm xuất hiện trong URL của mình. Chúng xuất hiện, vì URL được tạo và phải có thể đọc được.
mg30rg

2

Tùy thuộc vào mức độ quan trọng đối với bạn để giữ URI của bạn mà không cần truy vấn, bạn cũng có thể chuyển giá trị bằng dấu chấm như một phần của chuỗi truy vấn, không phải URI.

Ví dụ: www.example.com/people?name=michael.phelps sẽ hoạt động mà không phải thay đổi bất kỳ cài đặt hay bất cứ điều gì.

Bạn mất đi sự thanh lịch khi có một URI sạch, nhưng giải pháp này không yêu cầu thay đổi hoặc thêm bất kỳ cài đặt hoặc trình xử lý nào.


1

Có thể thay đổi cấu trúc URL của bạn?
Đối với những gì tôi đang làm việc tôi đã thử một tuyến đường cho

url: "Download/{fileName}"

nhưng nó đã thất bại với bất cứ thứ gì có trong đó.

Tôi đã chuyển tuyến đường sang

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

Bây giờ tôi có thể đặt localhost:xxxxx/File1.doc/Download và nó hoạt động tốt.

Những người giúp đỡ tôi trong tầm nhìn cũng nhặt được nó

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

điều đó tạo ra một liên kết đến localhost:xxxxx/File1.doc/Download định dạng là tốt.

Có lẽ bạn có thể đặt một từ không cần thiết như "/ view" hoặc hành động ở cuối tuyến để tài sản của bạn có thể kết thúc bằng một dấu vết /như/mike.smith/view


1

Nó đơn giản như thay đổi đường dẫn = " ." đến đường dẫn = " ". Chỉ cần xóa dấu chấm trong đường dẫn cho ExensionlessUrlHandler-Integration-4.0 trong web.config.

Đây là một bài viết hay https://weblog.west-wind.com/posts/2015/Nov/13/Serving-URLs-with-File-Extensions-in-an-ASPNET-MVC-Application


Liên kết này đưa tôi đến giải pháp tốt nhất cho vấn đề của mình (phân đoạn chứa ký tự "." Nhưng khách hàng sẽ không truy tìm dấu "/"). Đã sửa lỗi bằng cách có dòng này trong <system.webServer> của web.config - <mô-đun run ALLManagedModulesFor ALLRequests = "true" />
NickBeaugié 22/03/19

1

Đã thử tất cả các giải pháp trên nhưng không ai trong số họ làm việc cho tôi. Những gì đã làm là tôi gỡ cài đặt các phiên bản .NET> 4.5, bao gồm tất cả các phiên bản đa ngôn ngữ của nó; Cuối cùng, tôi đã thêm các phiên bản mới hơn (chỉ bằng tiếng Anh). Ngay bây giờ các phiên bản được cài đặt trên hệ thống của tôi là thế này:

  • 2.0
  • 3.0
  • 3,5 4
  • 4,5
  • 4.5.1
  • 4.5.2
  • 4.6
  • 4.6.1

Và nó vẫn hoạt động vào thời điểm này. Tôi sợ cài đặt 4.6.2 vì nó có thể làm hỏng mọi thứ.

Vì vậy, tôi chỉ có thể suy đoán rằng 4.6.2 hoặc tất cả các phiên bản không phải tiếng Anh đó đã làm rối cấu hình của tôi.


0

Tôi đã có thể giải quyết phiên bản cụ thể của mình về vấn đề này (phải tạo /customer.html định tuyến đến / khách hàng, không được phép cắt dấu gạch chéo) bằng cách sử dụng giải pháp tại https://stackoverflow.com/a/13082446/1454265 và đường dẫn thay thế = "*. Html".


0

Vì giải pháp cũng có thể được xem xét mã hóa thành định dạng không chứa ký hiệu ., như base64.

Trong js nên được thêm vào

btoa(parameter); 

Trong bộ điều khiển

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

0

Thêm quy tắc Viết lại URL vào lưu trữ Web.config. Bạn cần cài đặt mô-đun Rewrite URL trong IIS. Sử dụng quy tắc viết lại sau đây như là nguồn cảm hứng cho riêng bạn.

<?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

Ngoài ra, (liên quan) kiểm tra thứ tự ánh xạ xử lý của bạn. Chúng tôi đã có một .ashx với một .svc (ví dụ /foo.asmx/bar.svc/path) trong đường dẫn sau nó. Ánh xạ .svc trước tiên là 404 cho đường dẫn .svc khớp trước .asmx. Tôi không nghĩ quá nhiều nhưng có lẽ url mã hóa đường dẫn sẽ giải quyết việc này.


-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
Làm thế nào để trả lời câu hỏi của OP? Tâm mô tả nó xin vui lòng?
chèo thuyền kayak

Đó không phải là một giải pháp, đó là một bản hack yêu cầu phần mở rộng tệp được đặt vào đường dẫn uri (không có dấu chấm), ví dụ: "~ / Image / jpg / cow" để truy xuất tệp "/ app_data / hình ảnh / cow / jpg" - - không phải là giải pháp mà anh chàng này và mọi người khác tìm thấy nhu cầu này.
Shaun Wilson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.