Точки в 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");
}
}
}