Изменение маршрутов ASP.NET MVC динамически

Обычно, когда я смотрю на приложение ASP.Net MVC, таблица маршрутов настраивается при запуске и не затрагивается.

У меня есть несколько вопросов по этому поводу, но они тесно связаны друг с другом:

  • Можно ли изменить таблицу маршрутов во время выполнения?
  • Как мне/следует избегать проблем с потоками?
  • Может быть, лучший способ предоставить динамический URL? Я знаю, что идентификаторы и т.д. Могут отображаться в URL-адресе, но не могут видеть, как это может быть применимо в том, чего я хочу достичь.
  • Как я могу избежать этого, несмотря на то, что у меня установлен маршрут контроллера/действия по умолчанию, этот маршрут по умолчанию не работает для конкретной комбинации, например. действие "Опубликовать" в контроллере "Комментарии" недоступно по маршруту по умолчанию?

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

Ответ 1

Учитывая реальную проблему, обычный подход заключается в том, чтобы включить динамически созданный номер транзакции. Он должен храниться в скрытом поле формы, а также в словаре сеансов на стороне сервера и действителен только для одного запроса.

Я думаю, что сегодня многие механизмы обеспечивают такой механизм безопасности; тогда как этот тип атаки известен как Cross-Site-Request-Forgery (csrf).

Ответ 2

Я бы решил реализовать свой собственный IRouteHandler и поместить в пользовательский контроллер ControllerActionInvoker некоторую пользовательскую логику. Как это будет работать? Таблица маршрутов не будет динамически изменяться, но вы можете проверить свой пользовательский ControllerActionInvoker для случайного параметра в пути маршрута и вызвать или не выполнить соответствующее действие.

Мой маршрут:

routes.Add 
( 
    new Route 
        ( 
            "blog/comment/{*data}", 
            new RouteValueDictionary(new {controller = "blog", action = "comment", data = ""}), 
            new MyRouteHandler() 
        ) 
); 

Мой обработчик маршрута:

    class MyRouteHandler : IRouteHandler 
{ 

public IHttpHandler GetHttpHandler(RequestContext requestContext) 
    { 
        return new MyHttpHandler(requestContext); 
    } 
}`

Мой обработчик:

class MyHttpHandler : MvcHandler 
{ 
    public MyHttpHandler(RequestContext requestContext) : base(requestContext) 
    { 
    } 

    protected override void ProcessRequest(HttpContextBase httpContext) 
    { 
        IController controller = new BlogController(); 
        (controller as Controller).ActionInvoker = new MyActionInvoker(); 
        controller.Execute(RequestContext); 
    } }`

и мое действие ivoker, где должна быть закодирована пользовательская логика для обработки действия или нет:

    class MyActionInvoker : ControllerActionInvoker 
{ 
    protected override ActionResult InvokeActionMethod(MethodInfo methodInfo, IDictionary<string, object> parameters) 
    { 

        var data = ControllerContext.RouteData.GetRequiredString("data"); 


 // put my custom logic to check whetever I'll handle the action or not. The data could be a parameter in the database for that purpose.

        return base.InvokeActionMethod(methodInfo, parameters); 
    } 
} 

Я не знаю, что это лучшее решение, но на данный момент это тот, который приходит мне на ум.