Ресурс не может быть найден. ошибка, когда в конце URL стоит точка

Я использую бета-версию ASP .NET MVC и получаю ошибку HTTP 404 (ресурс не найден), когда использую этот URL-адрес с точкой в ​​конце:

http://localhost:81/Title/Edit/Code1.

Если я удалю точку в конце или точка окажется где-то посередине, я не получу сообщения об ошибке.

Я попытался выполнить отладку, но получил сообщение об ошибке «System.Web.CachedPathData.GetConfigPathData (String configPath)» перед ProcessRequest в MvcHandler.

Разве нельзя ставить точку в конце URL-адреса? Или есть способ исправить определение маршрута для обработки этого URL-адреса?


Например: у меня есть таблица с именем Detail1 [Id (integer), Code (строка), Description (строка)], которая имеет отношение FK к Master1 через его столбец Id. Всякий раз, когда я выбираю запись Master1, я также выбираю ее запись Detail1, чтобы получить ее поле Code. Чтобы не выполнять это соединение каждый раз (поскольку обычно не одна деталь, а несколько), я предпочитаю не использовать столбец Id и делаю код PK на Detail1.

Но когда я избавляюсь от идентификатора и использую Code как PK, мои маршруты также начинают работать с полем кода, например: Detail1 \ Edit \ Code1

В этом коде может быть что угодно или в конце, включая DOT. Бывают случаи, когда я могу запретить DOT в конце, но иногда это действительно имеет смысл.

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

Вот почему я делаю что-то настолько нестандартное. Какие-либо предложения?

А также почему так странно иметь точку в конце URL-адреса?


person ipek    schedule 09.01.2009    source источник
comment
не уверен, что это все еще играет для вас, но я добавил актуальное решение для более старых версий ASP.NET, проверьте это;).   -  person Abel    schedule 11.03.2011
comment
Если вы хотите добавить дополнительную информацию к своему вопросу, просто отредактируйте свой вопрос (нажмите ссылку «изменить» под своим вопросом). Чтобы прокомментировать полученный ответ, используйте функцию комментирования под ответом. Если вы обнаружите, что места для комментариев недостаточно, вам, вероятно, следует внести изменения. Ответы должны быть именно такими, прямыми ответами на ваш вопрос.   -  person Tim Post♦    schedule 14.10.2011


Ответы (6)


Если вы используете .NET 4.0, вы можете установить этот флаг в разделе system.web вашего web.config, и это будет разрешено:

<httpRuntime relaxedUrlToFileSystemMapping="true" />

Я протестировал это, и он работает. У Haack есть объяснение по этому поводу.

person bkaid    schedule 22.08.2010
comment
Спасибо, учту при обновлении до 4.0. Есть ли шанс для .NET 3.5? - person Jason; 14.01.2011
comment
@ Джейсон: да, есть способ для более старых версий .NET, взгляните на мой ответ. - person Abel; 11.03.2011
comment
Вы все знаете - позволит ли это URL-адресам, заканчивающимся точками, перенаправляться в модуль перезаписи URL-адресов в iis7.5? это то, что меня убивает прямо сейчас - person Brady Moritz; 09.02.2012
comment
Нет ли при этом проблем с безопасностью? - person Jake Gaston; 19.02.2015
comment
Я не верю, что это проблема безопасности. Согласно MSDN, этот параметр просто: ›указывает, должен ли URL-адрес в HTTP-запросе быть допустимым путем к файлу Windows. - person GWR; 13.11.2016

Это можно решить несколькими способами в каждой версии ASP.NET, начиная с 1.0. Я знаю, что прошло два года после того, как эта ветка была создана, но в любом случае вот она:

Причина

Создание собственного обработчика ошибок или настройка настраиваемой страницы в IIS для перенаправления 404 не сработает. Причина в том, что ASP.NET считает этот URL опасным. Внутри System.Web.Util.FileUtil ASP.NET вызывает частный метод IsSuspiciousPhysicalPath, который пытается сопоставить путь с (виртуальным, но допустимым) именем файла.

Когда полученный легализованный путь не равен исходному пути, обработка останавливается, и код ASP.NET возвращает 404 (он не запрашивает IIS или web.config для пользовательского 404, он возвращает его сам, что делает его таким сложно что-то с этим поделать).

Проводник Windows работает точно так же. Попробуйте создать имя файла, заканчивающееся одной или несколькими точками, например test.txt.. Вы обнаружите, что в результате получится имя text.txt.

Решение для завершения URL-адреса точкой в ​​ASP.NET

Решение простое (однажды вы знаете, что оно всегда так). Непосредственно перед отправкой этого 404 он вызовет Application_PreSendRequestHeaders < / a>, простое событие, на которое вы можете зарегистрироваться в Global.asax.cs (или его эквиваленте в VB). Следующий код вернет в браузер простой текст, но также возможен вариант «Перенаправление» или любой другой допустимый ответ.

protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{

    HttpResponse response = this.Context.Response;
    HttpRequest request = this.Context.Request;
    if (request.RawUrl.EndsWith("."))
    {
        response.ClearContent();
        response.StatusCode = 200;
        response.StatusDescription = "OK";
        response.SuppressContent = false;
        response.ContentType = "text/plain";
        response.Write("You have dot at the end of the url, this is allowed, but not by ASP.NET, but I caught you!");
        response.End();
    }
}

Примечание: этот код также работает, когда aspx не является частью URL-адреса. То есть, http://example.com/app/somepath. вызовет это событие. Также обратите внимание, что некоторые пути по-прежнему не работают (например, заканчиваясь несколькими точками, хэш-тегом или знаком ‹, вызывает 400-неверный запрос). Опять же, он работает для завершения цитатой, пробелом + косой чертой или несколькими точками, разделенными пробелами.

person Abel    schedule 11.03.2011
comment
это, вероятно, должно работать и в mvc, верно? человек, это было бы хорошо. - person Brady Moritz; 08.02.2012
comment
@boomhauer: да, используете ли вы MVC или нет, не имеет значения. - person Abel; 08.02.2012
comment
здорово, если описанная выше функция Relaxedurl не работает, я вернусь к этому. Благодарность - person Brady Moritz; 09.02.2012
comment
@boomhauer: RelaxedUrl работает в зависимости от того, какую версию .NET вы можете использовать. Кроме того, в тех случаях, когда вам нужен больший контроль (например: запретить все, кроме одного специального типа), проще сохранить безопасность, которую может дать вам relaxedUrlToFileSystemMapping="false". - person Abel; 10.02.2012
comment
@David: убедитесь, что ваше приложение .NET 3.5 запущено в среде CLR .NET 2.0 (нет среды CLR 3.0 или 3.5). Если вы запустите его в пуле приложений 4.0, я не удивлюсь, если он не сработает. Но я догадываюсь об источнике вашей проблемы. Возможно, вы захотите разработать и / или создать вопрос для вашего конкретного сценария. - person Abel; 25.08.2012
comment
У меня это не сработало на сайте .NET 4.0. Похоже, что это событие не происходит для страницы: /default.aspx .. По общему признанию, это сайт Umbraco, но другие запросы попадают сюда. На самом деле я пытался решить проблему появления "% 20" в конце - но в этом случае RawURL не включает% 20, и тогда он все равно будет 404, и я не буду мудрее в этом обработчике событий, что он собирается упасть. - person Ian Grainger; 02.07.2013
comment
@IanGrainger: для .NET 4.0 взгляните на решение, представленное в принятом ответе выше, от bkaid. Я верю, что это позволит вам их поймать. Однако имейте в виду, что несколько запросов (и я не уверен, что ваш является их частью) никогда не достигнут обработчиков ASP.NET. - person Abel; 22.07.2013
comment
@ Абель, да, я пытался избежать расслабленной проверки. - person Ian Grainger; 23.07.2013

Что ж, в .NET 4.5 я исправил эту проблему, добавив "/" в конец URL-адреса.

Итак, в вашем случае это будет «http: // localhost: 81 / Title / Edit / Code1. /». Это было единственное, что я сделал, мне не пришлось добавлять настройку httpRuntime.

person Nat    schedule 15.11.2012
comment
как вы добавили / в конце? - person mko; 16.07.2014

добавить это в обработчики

  <add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
 path="api/*"
 verb="*"
 type="System.Web.Handlers.TransferRequestHandler"
 preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
person Toolkit    schedule 15.12.2016

Возможно http://localhost:81/Title/Edit/Code1%2E сработает.

Я избежал точки с помощью шестнадцатеричного кода ascii.

person recursive    schedule 10.01.2009
comment
Не работает. Большинство браузеров меняют% 2E обратно на. перед отправкой запроса, поскольку это незарезервированный символ. - person Dan Fitch; 08.03.2010

Почему у вас не может быть URI, завершающегося точкой?

Поскольку URI - это запрос ресурса, а исторический императив существует во всех соответствующих операционных системах, точка - это разделитель расширений. Последняя точка трактуется как обозначающая расширение файла, поэтому ее завершение не имеет смысла.

Также стоит прочитать:

person annakata    schedule 10.01.2009
comment
RFC3986 ничего об этом не говорит. См. Раздел 3.3, где прямо говорится, что ... сегмент пути считается непрозрачным в соответствии с общим синтаксисом. - person Dan Fitch; 08.03.2010
comment
В URI нет такой вещи, как разделитель расширений. Вы по ошибке путаете имена файлов с URI. Они не одинаковы. - person Abel; 14.10.2011