如何将服务注入 Orchard 中的自定义 IHttpHandler

How to inject services into a custom IHttpHandler in Orchard

我正在为 Orchard 开发一个模块,它将通过查找经过身份验证的用户权限来限制媒体文件夹中的项目。

第一件事是像这样编辑 Media 文件夹中的 web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appSettings>
    <add key="webpages:Enabled" value="false" />
  </appSettings>
  <system.web>
    <httpHandlers>
      <add path="*" verb="*" type="MediaFileAccess.AuthorizedMediaHandler" />
    </httpHandlers>
  </system.web>
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
    </staticContent>
    <handlers accessPolicy="Script,Read">
      <add name="AuthorizedFile" path="*" verb="*"
           type="MediaFileAccess.AuthorizedMediaHandler,MediaFileAccess"
           preCondition="integratedMode" />
    </handlers>
  </system.webServer>
</configuration>

在web.config中注册的处理程序:

public class AuthorizedMediaHandler : IHttpHandler, IDependency
{
    private readonly IAuthenticationService _authenticationService;

    public AuthorizedMediaHandler(IAuthenticationService authenticationService)
    {
        _authenticationService = authenticationService;
    }

    public bool IsReusable { get { return false; } }

    public void ProcessRequest(HttpContext context)
    {
        // Do something using the injected services...
    }
}

当我导航到媒体项目时 url 系统抛出 MissingMethodException。这是正常的,因为系统找不到无参数构造函数。

那么,如何将 Orchard 服务注入 IHttpHandler?

你检查过 Glympse 了吗?使用 HttpHandlers,有一个 SO 问题 here

有一个讨论 here 让我开始思考。

让你的 web.configs 正常工作,应该没问题。我不知道 IDependency 位,可能不需要它。

你肯定不能注射。抱歉,我在之前的回答中省略了这一点。

您可以创建一个添加过滤器的 Orchard 模块,或者使用一个控制器劫持您指定的路由并从真正安全的地方提供文件。

Orchard 接管 IIS。这就是为什么您需要在文件夹 web.config 中添加静态文件模块以允许 IIS 进入,这就是它不安全的原因。

如果您真的需要走那条路,也许可以非常快速地调用 Orchard 服务或直接与数据库对话。

虽然您无法像这样注入依赖项,但您仍然可以使用 IShim 的魔力访问 Orchard 的 DI 容器。看看如何OrchardLog4netLogger 解析来自 IOrchardHostContainer 的依赖项。

请记住,虽然此容器是应用程序范围的容器:要能够解析您的标准 IDependency 类型,您需要首先从 [=15= 获取 ShellContext ],然后从其 LifetimeScope 创建一个 WorkContextScope 作为 LifetimeScope.CreateWorkContextScope()

我知道这看起来很复杂,而且确实有很多圈套。但最重要的是,通过这种方式,您可以在任何 class.

中解析来自 Orchard(及其 shell)的 DI 容器的服务