Как я могу использовать маршруты на основе атрибутов MVC5 с точкой / периодом в них?

В основном у меня есть готовое приложение MVC 5.2 с включенными маршрутами на основе атрибутов (вызов routes.MapMvcAttributeRoutes(); из предоставленного метода RouteConfig.RegisterRoutes(RouteCollection routes)).

Следующее находится в HomeController:

    [Route("hello.txt")]
    [Route("hellotxt-testing")]
    public ActionResult ShowFile()
    {
        return Content("Hello world");
    }

Я могу успешно получить доступ к /hellotxt-testing (доказывая, что маршрутизация на основе атрибутов работает правильно):

accessing / hellotxt-testing

Но я получаю страницу 404, если обращаюсь к /hello.txt:

доступ к /hello.txt

В отличие от того, когда я захожу на /hello404, я получаю другую страницу 404:

accessing / hello404

Я предполагаю, что вторая страница 404 - из ASP.NET, а первая - из IIS, который даже не передает запрос в ASP.NET?

Что мне делать, чтобы гарантировать, что ASP.NET получит эти URL-адреса, в которых есть точки? Существуют ли другие «специальные» символы, которые также могут вызвать проблемы?


person gregmac    schedule 10.01.2015    source источник
comment
пожалуйста, проверьте это stackoverflow.com/questions/11728846/   -  person Veena    schedule 24.02.2015
comment
Это исправление фактически требует модификации web.config для каждого пути, который может содержать точки. Мне это кажется безумием, должен быть способ получше. В ASP.NET уже есть список всех возможных шаблонов URL (таблица маршрутизации). Я бы подумал, что ASP.NET должен нести ответственность за то, чтобы IIS проходил через них (может быть, ASP.NET 6 добавляет это?). Но если это не так, можно ли сделать это динамически (например, написать обработчик, который регистрирует все известные маршруты с помощью IIS), или есть ограничение, которое помешало бы этому работать?   -  person gregmac    schedule 24.02.2015
comment
Вы пробовали <httpRuntime relaxedUrlToFileSystemMapping="true"/>?   -  person haim770    schedule 24.02.2015
comment
Думаю, мне было бы любопытно, зачем вам это нужно? Помимо этого, как уже было указано, маршрутизация игнорирует статические пути (поэтому IIS может делать такие вещи, как доставлять изображения и статические файлы в браузер). Это в значительной степени случай специфичности, игнорирование вещей, которые выглядят как «маршрут» статических файлов, появляется перед маршрутом hello.txt и разрешается первым. Ответ @rexilion имеет большое количество альтернатив.   -  person Vassi    schedule 28.02.2015


Ответы (2)


Разница между ошибками, которые вы видите, заключается в том, что при попытке доступа /hello.txt IIS пытается достичь статического файла ресурсов, расположенного на сервере, с другой стороны, /hello404 - это просто неизвестный маршрут, поэтому выдается 404.

Чтобы убедиться, что я прав, попробуйте добавить косую черту в конце и получить доступ к /hello.txt/, теперь вы должны получить ошибку 404.

Есть несколько способов решить эту проблему:

Сначала вы можете попробовать

<modules runAllManagedModulesForAllRequests="true">

но эта опция называется RAMMFAR

но тебе это не понравилось.

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


Я бы выбрал второй вариант, если вам нужно, чтобы он работал во многих местах вашего приложения.

Но я считаю, что лучший - третий. Такие URL-адреса с точками не удобны для пользователя и противоречат правилам SEO. Вам следует избегать их на общедоступных веб-сайтах. Предполагая, что вам это нужно только для одного контроллера и маршрута, этот вариант является самым быстрым и чистым.

person Piotr Leniartek    schedule 24.02.2015

У нас была такая же проблема (хотя и не с маршрутизацией атрибутов), она начала появляться в MVC 4 и с тех пор продолжается в каждой версии.

Один из участников нашего проекта обнаружил решение. Боюсь, я не могу подробно объяснить, почему, но удаление, а затем замена UrlRoutingModule устраняет проблему 404 при использовании маршрута с . в нем.

<configuration>
    <system.webServer>
        <modules>
            <remove name="UrlRoutingModule-4.0" />
            <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
        </modules>
    </system.webServer>
</configuration>

Это было обнаружено около 2 лет назад, и пока мы не столкнулись с какими-либо негативными эффектами, вызванными этим изменением.

Кстати - если у кого-то есть объяснение, почему это работает, поделитесь, пожалуйста.

person NightOwl888    schedule 24.02.2015
comment
Судя по всему, ваша директива add не учитывает предварительное условие о том, что модуль должен применяться только в контексте managedHandler. Я считаю, что ссылка по умолчанию на модуль, который вы удаляете, имеет следующую спецификацию: ‹add name = UrlRoutingModule-4.0 type = System.Web.Routing.UrlRoutingModule preCondition = managedHandler /› Итак, вы по существу применили UrlRouting к каждый запрос, будь то через managedHandler или нет. Дополнительная информация в разделе 2 по этому адресу: svenaelterman.wordpress.com/2011/01/31/ - person theta-fish; 22.02.2017