Точки в URL-адресе вызывают 404 с помощью ASP.NET mvc и IIS

У меня есть проект, который требует, чтобы мои URL-адреса имели точки в пути. Например, у меня может быть URL-адрес, например www.example.com/people/michael.phelps

URL-адреса с точкой генерируют 404. Моя маршрутизация прекрасна. Если я пройду в Майклапппс, без точки, тогда все будет работать. Если я добавлю точку, я получаю ошибку 404. Пример сайта работает в Windows 7 с IIS8 Express. URLScan не запущен.

Я попытался добавить следующее к моему web.config:

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

К сожалению, это не повлияло. Я просто получаю ошибку 404.0 Not Found.

Это проект MVC4, но я не думаю, что это актуально. Моя маршрутизация работает отлично, и параметры, которые я ожидаю, есть, пока они не включают точку.

Что мне нужно настроить, чтобы я мог иметь точки в моем URL?

Ответ 1

Я получил эту работу, отредактировав обработчики HTTP моего сайта. Для моих нужд это хорошо работает и решает мою проблему.

Я просто добавил новый обработчик HTTP, который ищет конкретные критерии пути. Если запрос соответствует, он корректно отправляется в .NET для обработки. Я гораздо счастливее с этим решением, что URLRewrite взломать или включить RAMMFAR.

Например, чтобы .NET обработал URL-адрес www.example.com/people/michael.phelps, добавьте следующую строку на ваш сайт web.config в элементе system.webServer / handlers:

<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

Есть и другие сообщения, в которых говорится о том, что решение этой проблемы - RAMMFAR или RunAllManagedModulesForAllRequests. Включение этой опции позволит всем управляемым модулям для всех запросов. Это означает, что статические файлы, такие как изображения, PDF файлы и все остальное, будут обрабатываться .NET, когда им этого не потребуется. Эти параметры лучше всего оставить, если у вас нет конкретного случая.

Ответ 2

После некоторого разговора я обнаружил, что relaxedUrlToFileSystemMapping не работает вообще для меня, что работало в моем случае, устанавливая RAMMFAR в true, то же самое верно для (.net 4.0 + mvc3) и (.net 4.5 + mvc4).

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

Помните, что при установке RAMMFAR true сообщение Hanselman о RAMMFAR и производительности

Ответ 3

Я считаю, что вы должны установить свойство relaxedUrlToFileSystemMapping в свой web.config. Haack написал статью об этом некоторое время назад (и есть и другие сообщения SO задавая те же типы вопросов)

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

Ответ 4

Просто добавьте этот раздел в Web.config, и все запросы к маршруту /{* pathInfo} будут обрабатываться указанным обработчиком, даже если в pathInfo есть точки. (взято из примера ServiceStack MVC Host Web.config и этого ответа fooobar.com/questions/26862/...)

Это должно работать как для IIS 6, так и для 7. Вы можете назначить определенные обработчики для разных путей после "маршрута", изменив путь = "*" в "добавить" элементы

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

Ответ 5

Я застрял в этой проблеме в течение долгого времени, следуя всем различным средствам безрезультатно.

Я заметил, что при добавлении косой черты [/] в конец URL-адреса, содержащего точки [.], он не выдавал ошибку 404 и фактически работал.

Я, наконец, решил проблему с помощью URL-переписывателя, такого как URL-адрес URL-адреса IIS, для просмотра определенного шаблона и добавления косой черты.

Мой URL-адрес выглядит так:/Contact/~firstname.lastname, поэтому мой шаблон просто:/Contact/~ (. * [^/]) $

Я получил эту идею от Скотта Форсайт, см. ссылку ниже: http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path

Ответ 6

Возможно, вы захотите подумать об использовании тире вместо периодов.

В Pro ASP MVC 3 Framework они предлагают это сделать дружественные URL-адреса:

Избегайте символов, кодов и последовательностей символов. Если вам нужно слово разделитель, используйте тире (/my-great-article). Подчеркивания недружественны, и URL-кодированные пробелы являются странными (/my + great + article) или отвратительными (/Мой %20great %20article).

В нем также упоминается, что URL-адреса должны быть легко прочитаны и изменены для людей. Возможно, причина думать об использовании тире вместо точки также происходит из той же книги:

Не используйте расширения имен файлов для HTML-страниц (.aspx или .mvc), но используйте их для специализированных типов файлов (.jpg,.pdf,.zip и т.д.). Веб-браузеры не заботятся о расширениях имен файлов, если вы правильно настроили MIME-тип, но люди все еще ожидают, что файлы PDF заканчиваются на .pdf

Таким образом, хотя период остается читаемым для людей (хотя и менее читаемым, чем тире, ИМО), он все равно может немного запутывать/вводить в заблуждение в зависимости от того, что происходит после периода. Что делать, если кто-то имеет фамилию zip? Тогда URL будет /John.zip вместо/John-zip, что может ввести в заблуждение даже разработчику, который написал приложение.

Ответ 7

Суперлегкий ответ для тех, у кого только есть это на одной веб-странице. Отредактируйте свою actionlink и + "/" в конце ее.

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

Ответ 8

Обходное решение 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/[email protected]

в

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

Ответ 9

Можно ли изменить структуру URL? Для чего я работал, я пробовал маршрут для

url: "Download/{fileName}"

но это не удалось с чем-либо, у которого был a. в нем.

Я переключил маршрут на

    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" или действие в конце вашего маршрута, чтобы ваше свойство могло закончиться конечным / чем-то вроде /mike.smith/view

Ответ 10

Пробовал все решения выше, но никто из них не работал у меня. Что я делал, я удалил версии .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, либо все эти неанглийские версии испортили мою конфигурацию.

HTH кто-то.

Ответ 11

Мне удалось решить мою конкретную версию этой проблемы (нужно было сделать /customer.html маршрут/клиент, недопустимые конечные косые черты) с помощью решения fooobar.com/questions/26882/... и подставляя путь = "*. html".

Ответ 12

Так как решение может также рассматривать кодирование в формате, который не содержит символ ., как base64.

В js следует добавить

btoa(parameter); 

В контроллере

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

Ответ 13

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");
        }
    }
}