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エラーをスローします。
マーク

15
マーク-これは、末尾のスラッシュがないと、IISはファイルを移動して検索する必要があると見なすためです。スラッシュを追加すると、次のような効果があります。これは実際のファイルではありません。さらに、以下の構成オプションは、ファイルでない場合は、代わりにルーティングするようにIISに指示します。
トミー

プロジェクトをmvc 4 + asp.net 4.5に更新した後も同じ問題が発生します。
Tadeu Maia

回避策として、URLに末尾のスラッシュを追加するためにIIS Rewriteを使用しています。
マーク・

4
これは私にはうまくいきません。URLは「。」で正常に機能します。URL内であるが、最後にある場合はエラーになる
アルカディアン

回答:


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
これを[path = "*"]で追加すると、.css、.jsなどの静的ファイルへのすべてのリクエストが失敗します。この「domain / ABCDE.FGHIJ」のようなURLを処理するカスタムルートがあります。静的ファイルはすべて/ Contentディレクトリにあります。これからディレクトリ全体を除外する方法はありますか?RAMMFARをtrueに設定しても機能しますが、そのオーバーヘッドを回避したいと思います。
ラマラント2013年

2
ローカルIISは開始スラッシュで機能しますが、IIS8は最初のスラッシュなしでのみルートを理解します。
Pavel Voronin 2013年

2
@lamarantと同じ問題が発生しています...静的ファイルをブロックします。なぜなのかご存知ですか?ここではMVC4を使用しています。
eestein、2014

3
これはMVC5で機能しますが、パスの先頭にスラッシュを入れた場合、パスがホスト名の直後にある場合にのみ機能します(アプリフォルダーに対して相対的ではありません)。たとえば、パス/ people / *はwww.example.com/people/michael.phelpsでは機能しますが、www.example.com / app / people / michael.phelpsでは機能しません。私の知る限り、アプリに対して相対的なパスを作成する方法はありません。
ホーガン

46

少し調べてみると、relaxedUrlToFileSystemMappingがまったく機能しないことがわかりました。私の場合、RAMMFARをtrueに設定すると、(。net 4.0 + mvc3)と(.net 4.5 + mvc4)に同じことが当てはまりました。

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

RAMMFARを設定する際は、RAMMFARとパフォーマンスに関する True Hanselmanの投稿に注意してください。


5
RAMMFARを設定するときは注意してください...この<modules runAllManagedModulesForAllRequests = "true">を使用するとパフォーマンスが低下しますか
Shanker Paudel

1
元のポスターの場合、IIS7以降を使用しているため、必要ありません。そこではそれがデフォルトであり、RAMMFARを設定すると実際にextaのコストがかかります。msdn.microsoft.com/en-us/library/…を
Richard

これは便利ですが、MVC5 / IIS7で404を返すのを停止する期間を確保するには不十分でした。
Chris Moschini、2016年

繰り返しますが、このオプションをオンにしたくない
Strake

ただし、可能であれば、ライブサイトではこれを行わないでください。
NickG 2018

27

web.configでプロパティrelaxedUrlToFileSystemMappingを設定する必要があると思います。 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
relaxedUrlToFileSystemMappingを試してみましたが、成功しませんでした。MVCの最新バージョンでは動作しないと思います。
マーク

これにより、/ WEB-INF。/ web.xmlというURLをキャッチし、他の多くの方法でうまくいかない場合にカスタムエラーページにリダイレクトすることができました。
quentin-starin 2013

3
面白い。あなたにとってそれがうまくいかなかったので、私はこれが私にとってはうまくいかないだろうと仮定しようとしていました... .NET4.5でMVC4を使用していることを考えると。しかし、ビンゴ、とにかくうまくいきました。私の場合、ピリオド "。"のURLがありました。最後の文字として。私は404を取得していましたが、これで修正されました。
PandaWood 2013年

彼にはセキュリティの影響がありますか?
Paesano2000

23

私はこの問題に長い間行き詰まってしまいました。

ドット[。]を含むURLの末尾にスラッシュ[/]を追加すると、404エラーがスローされず、実際に機能することに気付きました。

最後に、IIS URL RewriteのようなURLリライターを使用して問題を解決し、特定のパターンを監視してトレーニングスラッシュを追加しました。

私のURLは次のようになります:/Contact/~firstname.lastnameしたがって、私のパターンは次のようになります:/Contact/~(.*[^/])$

私はスコットフォーサイスからこのアイデアを得ました以下のリンクを参照してください。http//weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path


これは私(MVC5)のために働いた。上記の他の提案は機能せず、不要でした。末尾にスラッシュを付けただけです。@ jonduncan05によって提案されたルートをここで変更します
マルコウ2016年

レオン、ありがとう。私のためにその日を救った。ここで話題になっているすべてのweb.configについてはわかりませんが、末尾に/を追加することが必要な答えでした。私の場合、サーバー側のコントローラーとそれを呼び出していたJavaScriptを制御しているので、JavaScriptと更新を更新しました!
カエルPr1nce 2017年

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
runAllManagedModulesForAllRequests(RAMMFAR)がもたらすパフォーマンスへの影響に注意してください。これにより、すべてのリクエストに対してすべてのマネージモジュールが有効になります。画像などの静的ファイルはIISで直接処理できますが、これによりすべてのモジュールで処理され、すべての要求にオーバーヘッドが追加されます。
マーク

@MarkS。はい、ただし、<location>セクションを使用し、メインの<system.webServer>セクションでrunAllManagedModulesForAllRequestsを設定しない場合、これはroute / ...へのリクエストのみに影響すると考えています。
VB

@VB .NETが処理するはずのURLに一致するファイルがシステム上にない限り、ハンドラーだけで十分だと思います。そして、何らかの理由で、RAMMFARは<location>レベルでは機能しませんでしたが、ハンドラーソリューションは機能しました。
webXL 2013

@webXL <location>は、MVCが指定されたルートへのリクエストを処理してルートを追加しないようにする場合に必要です。IgnoreRoute( "route / {* pathInfo}"); 次に、IISはロケーションセクション<location path = "route">を調べ、指定されたハンドラーをロケーションセクションで使用しますが、MVCのルーティングと他のMVCのパイプラインステップを完全にバイパスします。私のプロジェクトでは、ServiceStack APIはそのセットアップなしでは機能しません。
VB

なぜハンドラを追加しないのですか?私の場合、ハンドラーと共にRAMMFARを追加する必要があります。ここで良い説明を探しています。:)
Aditya Patil 2015年

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

これを1つのWebページにのみ持っている人にとっては非常に簡単な答えです。アクションリンクを編集し、最後に+ "/"を付けます。

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

私のためにそれを解決しました!シンプルでエレガント!最も苛立たしいのは、開発中にWindows 10で「/」がなくても機能することですが、Windows 2012の場合は必須のようです。
Wim ten Brink 2017年

2

ピリオドの代わりにダッシュを使用することを検討してください。

プロASP MVC 3 Frameworkの彼らは友好的なURLをすることについて、これをお勧め:

記号、コード、文字シーケンスは避けてください。単語の区切り記号が必要な場合は、ダッシュ(/ my-great-article)を使用します。アンダースコアは不適切で、URLエンコードされたスペースは奇妙(/ my + great + article)または不快(/ my%20great%20article)です。

また、URLは人間にとって読みやすく、変更しやすいものでなければならないことにも言及しています。たぶん、ドットの代わりにダッシュを使うことを考える理由も同じ本から来ています:

HTMLページ(.aspxまたは.mvc)にはファイル名拡張子を使用しないでください。ただし、特殊なファイルタイプ(.jpg、.pdf、.zipなど)には使用してください。MIMEタイプを適切に設定すると、Webブラウザーはファイル名拡張子を気にしませんが、PDFファイルの末尾が.pdfであることを人間は期待しています

そのため、ピリオドは依然として人間には判読可能ですが(ダッシュよりも読みにくいですが、IMO)、ピリオドの後に何が来るかによっては、少し混乱したり、誤解を招く可能性があります。zipの姓がある場合はどうなりますか?その場合、URLは/ John-zipではなく/John.zipとなり、アプリケーションを作成した開発者にさえ誤解を招く可能性があります。


ドットが本質的に含まれているユーザー名または他のフィールドである可能性があります。そうは言っても、StackOverflowは.ユーザーURLのすべての句読点(を含む)をダッシュ​​に置き換えます:P
jli

ルートパラメータにファイル名が含まれている安全なファイル取得サービスがあるため、この問題に遭遇しました...
FlavorScape

明らかな理由で反対票を投じた:それは質問に答えません。できれば、URLにピリオドを表示させません。URLが生成され、人間が読めるようにする必要があるため、表示されます。
mg30rg 2018

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フォーマットへのリンクも作成します。

ルートの最後に「/ view」や「action」などの不要な単語を付けて、プロパティの末尾を/次のようにすることができます/mike.smith/view


1

これは、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


このリンクにより、問題の最善の解決策が得られました(セグメントには「。」文字が含まれていますが、クライアントは「/」で終了しません)。<system.webServer> web.configファイルの中でこのラインを持っていることによって、固定- <モジュールrunAllManagedModulesForAllRequests = "真" />
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

https://stackoverflow.com/a/13082446/1454265の解決策とパスを置き換えることで、この問題の特定のバージョン(/customer.htmlを/ customerにルーティングする必要があり、末尾のスラッシュは許可されていません)を解決できました= "*。html"。


0

解決策として、シンボルを含まない形式へのエンコードも検討できます.として、base64のようにます。

jsに追加する必要があります

btoa(parameter); 

コントローラ内

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

0

URL書き換えルールをWeb.configアーカイブに追加します。IISにURL Rewriteモジュールが既にインストールされている必要があります。次の書き換えルールを参考にしてください。

<?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パス(ピリオドなし)に配置する必要があるハックです。 -この男とこのニーズを見つけている他のすべての人の解決策ではありません。
Shaun Wilson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.