代码之家  ›  专栏  ›  技术社区  ›  flq

动态更改ASP.NET MVC路由

  •  11
  • flq  · 技术社区  · 15 年前

    通常,当我查看一个asp.net mvc应用程序时,路由表在启动时被配置,之后就再也不会被触及。

    对此我有几个问题,但它们之间有着密切的联系:

    • 是否可以在运行时更改路由表?
    • 如何避免线程问题?
    • 是否有更好的方法来提供动态url?我知道id等可以出现在url中,但看不出这如何适用于我想要实现的目标。
    • 即使我定义了默认的控制器/操作路由,如何避免默认路由对特定组合不起作用,例如“comments”控制器上的“post”操作无法通过默认路由使用?

    背景: 评论垃圾邮件发送者通常从网站上获取发布URL,然后不必再费心通过网站进行自动垃圾邮件发送。如果我定期修改我的文章的网址到某个随机的,垃圾邮件发送者将不得不回到网站,并找到正确的文章网址来尝试垃圾邮件。如果网址不断变化,我想这可能会使垃圾邮件发送者的工作更加乏味,这通常意味着他们放弃受影响的网址。

    2 回复  |  直到 10 年前
        1
  •  3
  •   agent_harris    10 年前

    考虑到实际的问题背景,通常的方法是包含一个动态创建的事务编号。它应该存储在一个隐藏的表单字段以及服务器端会话字典中,并且只对一个请求有效。

    我认为现在很多框架都提供了这样的安全机制;而这种攻击类型被称为跨站点请求伪造(csrf)。

        2
  •  11
  •   Tomasz Jaskuλa    15 年前

    我会考虑实现自己的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); 
        } }`
    

    以及我的action 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); 
        } 
    } 
    

    我不知道这是最好的解决办法,但现在我想到的是这个。