1

古时候:

我们使用了 Response.Redirect,它设置 302 响应标头并引发 ThreadAbortException 以防止在重定向后发生其他任何事情。

现在,使用 MVC:

我们返回一个 RedirectResult,它避免了 ThreadAbortException 的性能问题,并且还允许管道的其余部分在实际将结果发送回浏览器之前检查结果。这是对重定向的另一种思考方式——现在不是停止执行,重定向更像是从函数返回。

我的问题与混合和匹配这些模式有关。

这是要求。我们有一个 MVC 站点,站点包含一个负责身份验证的 HttpModule。如果身份验证出现任何问题,它会丢弃 cookie 并重定向到外部网页。因此 HttpModule 决定是发送重定向标头还是将控制权传递给 MVC 站点。如果它发送重定向标头,它必须停止执行——如果身份验证失败,我们不希望该站点以任何方式、形状或形式可访问。

这样做的“正确”方法是什么?HttpModule 应该像我们一直做的那样简单地使用 Response.Redirect 吗?或者是否有一些更符合 MVC 模式的巧妙方法来实现这一点?HttpModule 有没有办法告诉管道停止处理?

或者我应该使用一些完全不同的模式,不使用 HttpModule 的东西?也许是 MVC 过滤器?问题是,模块和站点本身之间的模块化/关注点分离非常重要。有人有什么建议吗?

4

2 回答 2

2

以为我会在这里提出答案,以防其他人在类似的问题域中有问题。

答案其实很简单。

HttpContext.ApplicationInstance.CompleteRequest()

上面的调用不再抛出 ThreadAbortException(这在 .NET 2.0 中发生了变化),因此您可以安全地使用它来告诉管道停止执行。当 HttpModule 退出时,适当的网站被绕过,控制直接转到 EndRequest——这正是我所需要的。这在 .NET 1.1 中是不可能的,但我认为没有很多 1.1 MVC 项目;)

于 2013-04-14T07:59:54.447 回答
1

由于您提到这是用于身份验证,因此您应该使用Authorize Attribute。您可以在类级别或操作级别使用它。

[Authorize]
public class HomeController : Controller
{
    // All actions will require authorization
}

public class ImageController : Controller
{
    public ActionResult PublicImage()
    {
    }

    [Authorize]
    public ActionResult ImageRequiringAuth()
    {
    }
}

对于您的用例,您可能需要从 AuthorizationAttribute 继承,如本答案中所述。

于 2013-04-13T11:19:50.333 回答