Dots di URL menyebabkan 404 dengan ASP.NET mvc dan IIS

303

Saya memiliki proyek yang mengharuskan URL saya memiliki titik di jalur. Misalnya saya dapat memiliki URL seperti www.example.com/people/michael.phelps

URL dengan titik menghasilkan 404. Rute saya baik-baik saja. Jika saya melewati michaelphelps, tanpa titik, maka semuanya berfungsi. Jika saya menambahkan titik saya mendapatkan kesalahan 404. Situs sampel dijalankan pada Windows 7 dengan IIS8 Express. URLScan tidak berjalan.

Saya mencoba menambahkan yang berikut ke web.config saya:

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

Sayangnya itu tidak membuat perbedaan. Saya baru saja menerima kesalahan 404.0 Tidak Ditemukan.

Ini adalah proyek MVC4 tapi saya pikir itu tidak relevan. Routing saya berfungsi dengan baik dan parameter yang saya harapkan ada di sana, sampai mereka menyertakan titik.

Apa yang harus saya konfigurasi agar saya dapat memiliki titik-titik di URL saya?

Menandai
sumber
93
Tidak percaya saya menghabiskan banyak waktu untuk ini. URL berfungsi dengan baik jika saya menambahkan garis miring. Misalnya, www.example.com/people/michael.phelps/ namun tanpa garis miring IIS melempar kesalahan 404.
Tandai
15
Tandai - itu karena tanpa garis miring, IIS berpikir itu adalah file yang harusnya ditemukan dan ditemukan. Menambahkan garis miring memiliki efek ... ini bukan file asli. Selain itu, opsi konfigurasi di bawah ini memberi tahu IIS bahwa jika itu bukan file, cobalah untuk merutekannya.
Tommy
Saya mengalami masalah yang sama setelah saya memperbarui proyek saya ke mvc 4 + asp.net 4.5.
Tadeu Maia
Sebagai solusi, saya menggunakan IIS Rewrite untuk menambahkan garis miring ke URL saya.
Mark
4
Ini tidak berhasil untuk saya. URL berfungsi dengan baik dengan "." dalam URL tetapi ketika itu di bagian paling akhir ia memberikan kesalahan
Arcadian

Jawaban:

379

Saya mendapatkan ini berfungsi dengan mengedit handler HTTP situs saya. Untuk kebutuhan saya ini berfungsi dengan baik dan menyelesaikan masalah saya.

Saya hanya menambahkan handler HTTP baru yang mencari kriteria jalur tertentu. Jika permintaan cocok, itu dikirim dengan benar ke .NET untuk diproses. Saya jauh lebih bahagia dengan solusi ini bahwa URLRewrite meretas atau mengaktifkan RAMMFAR.

Misalnya, agar .NET memproses URL www.example.com/people/michael.phelps menambahkan baris berikut ke web.config situs Anda di dalam system.webServer / handlerselemen:

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

Edit

Ada posting lain yang menunjukkan bahwa solusi untuk masalah ini adalah RAMMFARatau RunAllManagedModulesForAllRequests. Mengaktifkan opsi ini akan mengaktifkan semua modul yang dikelola untuk semua permintaan. Itu berarti file statis seperti gambar, PDF, dan yang lainnya akan diproses oleh .NET ketika tidak diperlukan. Opsi ini sebaiknya tidak digunakan kecuali Anda memiliki kasus khusus untuk itu.

Menandai
sumber
3
berikut ini adalah contoh lengkap stackoverflow.com/a/16607685/801189 berdasarkan jawaban ini
VB
10
setelah menambahkan ini dengan [path = "*"] semua permintaan ke file statis seperti .css, .js gagal. Saya memiliki rute khusus yang menangani url yang terlihat seperti " domain / ABCDE.FGHIJ " ini. Semua file statis saya ada di direktori / Konten saya. Apakah ada cara untuk mengecualikan seluruh direktori dari ini? pengaturan RAMMFAR untuk pekerjaan nyata tetapi saya ingin menghindari overhead itu.
Lamarant
2
IIS lokal bekerja dengan memulai slash, tetapi IIS8 memahami rute hanya tanpa slash pertama.
Pavel Voronin
2
Saya mengalami masalah yang sama dengan @lamarant ... Memblokir file statis. Apa kamu tahu kenapa? Menggunakan MVC4 di sini.
eestein
3
Ini bekerja di MVC5, tetapi jika Anda meletakkan garis miring di awal jalan, itu bekerja hanya ketika jalan langsung setelah nama host (itu tidak relatif ke folder aplikasi). Misalnya path / people / * akan berfungsi untuk www.example.com/people/michael.phelps, tetapi tidak untuk www.example.com/app/people/michael.phelps. AFAIK tidak ada cara untuk membuat jalur relatif ke aplikasi.
Hogan
46

Setelah beberapa mengaduk-aduk saya menemukan bahwa relaxingUrlToFileSystemMapping tidak berfungsi sama sekali bagi saya, apa yang berhasil dalam kasus saya adalah pengaturan RAMMFAR menjadi true, hal yang sama berlaku untuk (.net 4.0 + mvc3) dan (.net 4.5 + mvc4).

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

Berhati-hatilah saat mengatur RAMMFAR posting Hanselman tentang RAMMFAR dan kinerja

Tadeu Maia
sumber
5
Berhati-hatilah saat mengatur RAMMFAR ... Apakah ada kehilangan kinerja jika saya menggunakan <module runAllManagedModulesForAllRequests = "true">
Shanker Paudel
1
Dalam hal poster aslinya tidak perlu, karena ia menggunakan IIS7 dan di atasnya. Itu adalah default dan pengaturan RAMMFAR memang membebani Anda. Lihat msdn.microsoft.com/en-us/library/…
Richard
Meskipun ini berguna, ini tidak cukup untuk mendapatkan periode untuk berhenti mengembalikan 404s di MVC5 / IIS7 untuk saya.
Chris Moschini
Hanya untuk mengulangi. Anda ingin menghindari opsi ini dihidupkan
Strake
Jangan lakukan ini di situs langsung, jika memungkinkan.
NickG
27

Saya percaya Anda harus mengatur properti santaiUrlToFileSystemMapping di web.config Anda. Haack menulis artikel tentang ini beberapa waktu yang lalu (dan ada beberapa posting SO lainnya yang menanyakan jenis pertanyaan yang sama)

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

Edit Dari komentar di bawah ini, versi .NET / IIS yang lebih baru mungkin mengharuskan ini ada di system.WebServerelemen.

<system.webServer>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
Tommy
sumber
2
Inilah yang saya miliki dengan mvc3 + .net4.0 dan bekerja dengan indah, tetapi tidak berfungsi lagi dengan mvc4 + .net4.5.
Tadeu Maia
4
Saya mencoba PemetaanUllToFileSystemSantai tanpa hasil. Saya tidak berpikir itu berfungsi dengan versi terbaru dari MVC.
Markus
Ini memungkinkan saya untuk menangkap url /WEB-INF./web.xml dan mengarahkannya ke halaman kesalahan khusus ketika banyak cara lain yang saya coba tidak berhasil.
quentin-starin
3
Menarik. Mengingat bahwa itu tidak bekerja untuk Anda, saya akan menganggap ini tidak akan berhasil untuk saya ... mengingat saya menggunakan MVC4 dengan .NET4.5. Tapi bingo, itu berhasil. Dalam kasus saya, saya hanya punya URL dengan tanda "." sebagai karakter terakhir. Saya mendapatkan 404 tetapi ini memperbaikinya.
PandaWood
Apakah ia memiliki dampak keamanan?
Paesano2000
23

Saya terjebak pada masalah ini untuk waktu yang lama mengikuti semua solusi yang berbeda tanpa hasil.

Saya perhatikan bahwa ketika menambahkan garis miring [/] ke akhir URL yang berisi titik [.], Itu tidak menghasilkan kesalahan 404 dan itu benar-benar berfungsi.

Saya akhirnya menyelesaikan masalah menggunakan penulis ulang URL seperti IIS URL Rewrite untuk melihat pola tertentu dan menambahkan garis miring pelatihan.

URL saya terlihat seperti ini: /Contact/~firstname.lastname jadi polanya hanya: /Contact/~(.*[^/[)$

Saya mendapatkan ide ini dari Scott Forsyth, lihat tautan di bawah ini: http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path

Leon van Wyk
sumber
Ini bekerja untuk saya (MVC5). Saran lain di atas tidak berhasil, dan tidak diperlukan, hanya garis miring. Saya akan mengubah rute saya seperti yang disarankan oleh @ jonduncan05 di sini .
markau
Terima kasih, Leon. Menyimpan hari untukku. Tidak yakin tentang semua hal web.config yang dibicarakan orang di sini, tetapi menambahkan trailing / adalah jawaban yang saya butuhkan. Dalam kasus saya, saya memiliki kendali atas pengontrol sisi-server, dan javascript yang memanggilnya, jadi saya baru saja memperbarui JavaScript dan voila!
Frog Pr1nce
21

Cukup tambahkan bagian ini ke Web.config, dan semua permintaan ke rute / {* pathInfo} akan ditangani oleh penangan yang ditentukan, bahkan ketika ada titik di pathInfo. (diambil dari contoh Web.config Host Host.Config dan jawaban ini https://stackoverflow.com/a/12151501/801189 )

Ini harus bekerja untuk IIS 6 & 7. Anda dapat menetapkan penangan spesifik ke jalur yang berbeda setelah 'rute' dengan memodifikasi jalur = "*" di elemen 'tambah'

  <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>
VB
sumber
2
Waspadalah terhadap konsekuensi kinerja yang dimiliki oleh runAllManagedModulesForAllRequests (RAMMFAR). Ini akan memungkinkan semua modul yang dikelola untuk setiap permintaan. File statis, seperti gambar, dapat diproses oleh IIS secara langsung tetapi ini memprosesnya melalui setiap modul yang menambahkan overhead untuk setiap permintaan.
Tandai
@Tanda. ya, tapi saya yakin ini hanya akan memengaruhi permintaan untuk merutekan / ... jika kita menggunakan bagian <lokasi> dan tidak menyetel runAllManagedModulesForAllRequests di bagian <system.webServer> utama.
VB
@ VB Saya pikir hanya penangan sudah cukup, kecuali Anda memiliki file pada sistem yang cocok dengan URL yang .NET seharusnya diproses. Dan untuk beberapa alasan, RAMMFAR tidak berfungsi pada level <lokasi>, tetapi solusi pawang berhasil.
webXL
@webXL <lokasi> diperlukan saat Anda tidak ingin MVC memproses permintaan ke rute yang ditentukan dan menambahkan rute.IgnoreRoute ("route / {* pathInfo}"); Kemudian IIS akan melihat ke bagian lokasi <lokasi jalur = "rute"> dan akan menggunakan penangan yang ditentukan di bagian lokasi, tetapi itu akan memotong sepenuhnya routing MVC dan langkah-langkah pipa MVC lainnya. Dalam proyek saya, api ServiceStack tidak berfungsi tanpa pengaturan itu.
VB
Mengapa tidak hanya menambahkan pekerjaan pawang? Dalam kasus saya, saya harus menambahkan RAMMFAR bersama dengan pawang. Mencari penjelasan yang bagus di sini. :)
Aditya Patil
6

Penanganan masalah MVC 5.0.

Banyak jawaban yang disarankan tampaknya tidak berfungsi di MVC 5.0.

Karena masalah 404 dot di bagian terakhir dapat diselesaikan dengan menutup bagian itu dengan garis miring, inilah trik kecil yang saya gunakan, bersih dan sederhana.

Sambil menjaga placeholder yang nyaman dalam pandangan Anda:

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

tambahkan sedikit jquery / javascript untuk menyelesaikan pekerjaan:

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

harap perhatikan garis miring, yang bertanggung jawab untuk mengubah

http://localhost:51003/GeoData/Manage/[email protected]

ke

http://localhost:51003/GeoData/Manage/[email protected]/
Luke
sumber
5

Jawaban super mudah bagi mereka yang hanya memiliki ini pada satu halaman web. Edit tautan tindakan Anda dan tanda + "/" di bagian akhir.

  @Html.ActionLink("Edit", "Edit", new { id = item.name + "/" }) |
Jeremy Hobbs
sumber
Memecahkannya untukku! Sederhana dan elegan! Paling menjengkelkan adalah bahwa ia bekerja tanpa '/' pada Windows 10 selama pengembangan, tetapi untuk Windows 2012 tampaknya diperlukan.
Wim ten Brink
2

Anda mungkin ingin berpikir tentang menggunakan tanda hubung bukan titik.

Dalam Pro ASP MVC 3 Framework mereka menyarankan ini tentang membuat URL yang ramah:

Hindari simbol, kode, dan urutan karakter. Jika Anda menginginkan pemisah kata, gunakan tanda hubung (/ my-great-article). Garis bawah tidak ramah, dan ruang yang disandikan URL aneh (/ artikel + besar + saya) atau menjijikkan (/% mygreat% 20article).

Itu juga menyebutkan bahwa URL harus mudah dibaca dan diubah untuk manusia. Mungkin alasan untuk berpikir tentang menggunakan tanda hubung bukan titik juga berasal dari buku yang sama:

Jangan gunakan ekstensi nama file untuk halaman HTML (.aspx atau .mvc), tetapi gunakan ekstensi tersebut untuk jenis file khusus (.jpg, .pdf, .zip, dll). Browser web tidak peduli dengan ekstensi nama file jika Anda mengatur jenis MIME dengan tepat, tetapi manusia masih berharap file PDF diakhiri dengan .pdf

Jadi, sementara suatu periode masih dapat dibaca oleh manusia (meskipun kurang dapat dibaca daripada garis, IMO), itu mungkin masih sedikit membingungkan / menyesatkan tergantung pada apa yang datang setelah periode. Bagaimana jika seseorang memiliki nama belakang zip? Maka URL akan menjadi / John.zip bukan / John-zip, sesuatu yang bisa menyesatkan bahkan untuk pengembang yang menulis aplikasi.

sdm350
sumber
Kemungkinan nama pengguna atau bidang lain yang secara inheren berisi titik-titik. Yang mengatakan, StackOverflow menggantikan semua tanda baca (termasuk .) dengan tanda hubung di url penggunanya: P
jli
Saya mengalami ini karena saya memiliki layanan pengambilan file aman yang jelas berisi nama file dalam parameter rute ...
FlavourScape
Turun karena alasan yang jelas: Itu tidak menjawab pertanyaan. Jika saya bisa, saya tidak akan membiarkan titik muncul di URL saya. Mereka muncul, karena URL dibuat dan harus dapat dibaca manusia.
mg30rg
2

Bergantung pada betapa pentingnya bagi Anda untuk menjaga URI Anda tanpa querystrings, Anda juga bisa hanya memberikan nilai dengan titik-titik sebagai bagian dari querystring, bukan URI.

Misalnya www.example.com/people?name=michael.phelps akan berfungsi, tanpa harus mengubah pengaturan apa pun.

Anda kehilangan keanggunan memiliki URI bersih, tetapi solusi ini tidak perlu mengubah atau menambahkan pengaturan atau penangan.

GR7
sumber
1

Apakah mungkin mengubah struktur URL Anda?
Untuk apa saya sedang mengerjakan saya mencoba rute

url: "Download/{fileName}"

tetapi gagal dengan apa pun yang memiliki. di dalamnya.

Saya beralih rute ke

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

Sekarang saya bisa memasukkan localhost:xxxxx/File1.doc/Downloaddan berfungsi dengan baik.

Pembantu saya dalam tampilan juga mengambilnya

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

yang membuat tautan ke localhost:xxxxx/File1.doc/Downloadformat juga.

Mungkin Anda bisa meletakkan kata yang tidak dibutuhkan seperti "/ view" atau tindakan di akhir rute Anda sehingga properti Anda dapat diakhiri dengan /sesuatu yang tertinggal seperti/mike.smith/view

jonduncan05
sumber
1

Ini sesederhana mengubah path = " ." ke jalur = " ". Hapus saja titik di jalur untuk ExensionlessUrlHandler-Integrated-4.0 di web.config.

Berikut adalah artikel yang bagus https://weblog.west-wind.com/posts/2015/Nov/13/Serving-URLs-with-File-Extensions-in-an-ASPNET-MVC-Application

Jonny
sumber
Tautan ini mengarahkan saya ke solusi terbaik untuk masalah saya (segmen tersebut berisi karakter "." Tetapi klien tidak akan melacak dengan "/"). Diperbaiki dengan memiliki baris ini di <system.webServer> dari web.config - <modules runAllManagedModulesForAllRequests = "true" />
NickBeaugié
1

Sudah mencoba semua solusi di atas, tetapi tidak ada yang bekerja untuk saya. Apa yang berhasil adalah saya mencopot pemasangan .NET versi> 4.5, termasuk semua versi multibahasanya; Akhirnya saya menambahkan versi yang lebih baru (hanya bahasa Inggris) sepotong demi sepotong. Sekarang versi yang diinstal pada sistem saya adalah ini:

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

Dan masih bekerja pada saat ini. Saya takut menginstal 4.6.2 karena mungkin mengacaukan semuanya.

Jadi saya hanya bisa berspekulasi bahwa 4.6.2 atau semua versi non-Inggris itu mengacaukan konfigurasi saya.

jokab
sumber
0

Saya dapat menyelesaikan versi khusus masalah ini (harus membuat /customer.html rute ke / pelanggan, tidak mengikuti garis miring) menggunakan solusi di https://stackoverflow.com/a/13082446/1454265 , dan mengganti jalur = "*. html".

pengguna1454265
sumber
0

Sebagai solusi juga dapat mempertimbangkan pengkodean ke format yang tidak mengandung simbol. , seperti base64.

Dalam js harus ditambahkan

btoa(parameter); 

Di controller

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

Tambahkan aturan penulisan ulang URL ke arsip Web.config. Anda harus sudah menginstal modul URL Rewrite di IIS. Gunakan aturan penulisan ulang berikut sebagai inspirasi untuk Anda sendiri.

<?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> 
Amadeus Sánchez
sumber
0

Juga, (terkait) periksa urutan pemetaan pawang Anda. Kami memiliki .ashx dengan .svc (mis. /Foo.asmx/bar.svc/path) di jalur setelahnya. Pemetaan .svc pertama kali jadi 404 untuk jalur .svc yang cocok dengan sebelum .asmx. Aku tidak berpikir terlalu banyak, tetapi mungkin url yang mengkodekan jalan akan membereskan ini.

stuartm9999
sumber
-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");
        }
    }
}
hamyari afarinesh
sumber
1
Bagaimana ini menjawab pertanyaan OP? Pikiran bisa menggambarkannya tolong?
kayess
itu bukan solusi, ini adalah peretasan yang membutuhkan ekstensi file untuk ditempatkan ke jalur uri (tanpa titik) mis. "~ / Gambar / jpg / cow" untuk mengambil file "/ app_data / images / cow / jpg" - - bukan solusi orang ini dan orang lain yang menemukan kebutuhan ini.
Shaun Wilson