【问题标题】:HttpModule only on specific MVC routeHttpModule 仅在特定 MVC 路由上
【发布时间】:2013-04-03 21:51:12
【问题描述】:

我有一个自定义 IHttpModule,我只想在特定路线上工作。

例如:http://example.com/HandleAzureTask

我希望这个模块只在/HandleAzureTask 路由上被调用/处理。

由于这不是控制器,我无法真正设置[Authorize] 属性;如果用户经过身份验证,如何强制它仅被调用/处理?

我在 ASP.NET MVC 4 上,目前已将我的模块添加到 web.config 中:

<modules>
  <remove name="AzureWebDAVModule" />
  <add name="AzureWebDAVModule" type="VMC.WebDAV.Azure.Module.AzureWebDAVModule, VMC.WebDAV.Azure.Module" />
</modules>

【问题讨论】:

  • 我建议为这条​​路线创建自定义路线约束...
  • 你的 HttpModule 在做什么?如果您仅在此 ASP.NET MVC 应用程序上使用此模块,则可以考虑将其重写为操作过滤器。
  • 我有一个 WebDav 服务器 IHttpModule 来处理办公应用程序和 Azure Blob 存储之间的交互。
  • 是否需要将该代码保留为模块?如果没有,我建议将其重构为控制器/操作方法,以便您可以利用 MVC 授权。然后,相应地使用路由集合。
  • @darwindave 这个问题部分是由于我正在进行的一个项目。你可以在这里看到它:mvc4webdav.codeplex.com

标签: asp.net-mvc asp.net-mvc-4 routes httpmodule


【解决方案1】:

在每个请求上都会调用 HttpModules(相反,可以过滤 HttpHandlers)。如果您只想在选定的路线上执行任务,您可以执行以下操作:

这样设置路线:

routes.MapRoute(
    name: "AzureWebDAVRoute",
    url: "HandleAzureTask",
    // notice the enableHandler parameter
    defaults: new { controller = "YourController", action = "YourAction", enableHandler = true }
);

在你的模块上:

public class AzureWebDAVModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        // you can't directly access Request object here, it will throw an exception
        context.PostAcquireRequestState += new EventHandler(context_PostAcquireRequestState);
    }

    void context_PostAcquireRequestState(object sender, EventArgs e)
    {
        HttpApplication context = (HttpApplication)sender;
        RouteData routeData = context.Request.RequestContext.RouteData;

        if (routeData != null && routeData.Values["enableHandler"] != null)
        {
            // do your stuff
        }
    }

    public void Dispose()
    {
        //
    }
}

现在您的任务将仅在选定的路线上执行。请注意,您需要该参数,因为您无法按名称找到当前路线。

【讨论】:

  • Luca,这是否意味着我必须有一个实际控制人?如果是,我是否在控制器上设置 [authorize] 标签?如果没有,我将如何通过自定义过滤器在路由级别将 [authorize] 标签添加到“HandleAzureTask”控制器?因此,基本上每次加载某些内容时仍会调用 HttpModule,但仅在 routeData.Values["enableHandler"] != null 时才会起作用。我将它用于 WebDav 文件存储,但实际文件存储在 Azure Blob 中。
  • @dotsa [Authorize] 属性在这里几乎没有影响,因为 HttpModule 将被调用无论如何。如果要过滤对模块的访问,可以添加 Request.IsAuthenticated 条件。问题是您使用的是 HttpModule,并且此类组件已集成到 ASP.NET 管道中。请注意,HttpHandlers 与模块不同,可以支持路径参数。
  • 这种场景下控制器的必要性是什么。我也可以在 IHttpModule 中过滤 url 参数,如果它包含“HandleAzureTask”,那么句柄就会做它的事情。我错过了什么吗?或者通过使用控制器我们可以添加 [Authorize] 属性?
  • @dotsa 在这种情况下,我认为控制器和操作方法无关紧要。您实际执行的模块代码(在 if 内部)需要覆盖响应内容。
【解决方案2】:

为什么不直接创建一个名为 /HandleAzureTask 的普通文件夹,然后在该文件夹中放置一个单独的 web.config 并注册模块。

然后该模块将针对该文件夹中的所有请求运行。

要获得授权,您还可以在 web.config 中将授权元素设置为禁止 *

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 2021-10-17
    • 2019-06-14
    • 2019-08-27
    • 1970-01-01
    相关资源
    最近更新 更多