Изменять ASP.NET Маршруты MVC динамически
-
22-09-2019 - |
Вопрос
обычно, когда я смотрю на приложение ASP.Net MVC, таблица маршрутов настраивается при запуске и с тех пор к ней не прикасаются.
У меня есть пара вопросов по этому поводу, но они тесно связаны друг с другом:
- Можно ли изменить таблицу маршрутов во время выполнения?
- Как бы / я должен избегать проблем с потоками?
- Может быть, есть лучший способ предоставить динамический URL-адрес?Я знаю, что идентификаторы и т.д.может отображаться в URL-адресе, но не вижу, как это может быть применимо к тому, чего я хочу достичь.
- Как я могу избежать этого, даже если у меня определен маршрут контроллера / действия по умолчанию, этот маршрут по умолчанию не работает для определенной комбинации, напримердействие "Опубликовать" на контроллере "Комментарии" недоступно по маршруту по умолчанию?
Предыстория: Спамеры с комментариями обычно получают URL-адрес публикации с веб-сайта, а затем больше не утруждают себя автоматической рассылкой спама через веб-сайт.Если я регулярно изменяю URL-адрес своей публикации на какой-нибудь случайный, спамерам придется возвращаться на сайт и находить правильный URL-адрес публикации, чтобы попытаться рассылать спам.Если этот URL-адрес постоянно меняется, я бы подумал, что это может сделать работу спамеров более утомительной, что обычно должно означать, что они откажутся от затронутого URL-адреса.
Решение
Учитывая фактическую предысторию проблемы, обычный подход заключается в включении динамически создаваемого номера транзакции.Он должен храниться в скрытом поле формы, а также в словаре сеансов на стороне сервера и быть действительным только для одного запроса.
Я думаю, что сегодня многие фреймворки предоставляют такой механизм безопасности;принимая во внимание, что этот тип атаки известен как подделка межсайтовых запросов (csrf).
Другие советы
Я бы подумал о том, чтобы реализовать свой собственный IRouteHandler и поместить некоторую пользовательскую логику в мой пользовательский ControllerActionInvoker.Как это будет работать ?Таблица маршрутов не будет динамически изменяться, но вы могли бы проверить в вашем пользовательском ControllerActionInvoker наличие случайного параметра в пути маршрута и вызвать или нет соответствующее действие.
Мой маршрут :
routes.Add
(
new Route
(
"blog/comment/{*data}",
new RouteValueDictionary(new {controller = "blog", action = "comment", data = ""}),
new MyRouteHandler()
)
);
Мой обработчик маршрута I :
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);
}
}
Я не уверен, что это лучшее решение, но на данный момент это то, что приходит мне в голову.