使用ASP.NET MVC时将Global.asax移动到iHttpModule

时间:2010-06-05 20:38:35

标签: asp.net-mvc global-asax

我已经成功创建了一个iHttpModule来替换许多Web窗体应用程序中的Global.asax文件。但是在查看我的MVC应用程序中的Global.asax文件时,方法完全不同。

我想知道是否仍然可以在MVC应用程序中创建相同的东西。我知道没有必要,Global.asax工作得很好。我想我只想在我的应用程序的根目录中只有web.config。

另外,我将所有类放在一个单独的类库项目中,而不是放在我的MVC应用程序中的文件夹中。不确定这是否有所作为。

这是我目前所拥有的,但不幸的是我的路线没有注册

MVCApplication.vb(Class)

Imports System.Web.Mvc
Imports System.Web.Routing
Imports System.Web
Imports System.Text.RegularExpressions

Public Class MvcApplication : Inherits System.Web.HttpApplication : Implements IHttpModule

#Region "Global Variables/Objects"

    Private UrlRegex As New Regex("(http|https)://www\.", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
    Private ApplicationContext As HttpApplication
    Private BeginRequestEventHandler As EventHandler
    Private ErrorEventHandler As EventHandler
#End Region

#Region "Init and Dispose"

    Public Overrides Sub Dispose() Implements System.Web.IHttpModule.Dispose
        RemoveHandler ApplicationContext.BeginRequest, BeginRequestEventHandler : BeginRequestEventHandler = Nothing
        RemoveHandler ApplicationContext.Error, ErrorEventHandler : ErrorEventHandler = Nothing
    End Sub

    Public Overridable Overloads Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
        ApplicationContext = context
        AddHandler ApplicationContext.BeginRequest, AddressOf OnBeginRequest
        AddHandler ApplicationContext.Error, AddressOf OnError
    End Sub
#End Region

    Protected Sub OnBeginRequest(ByVal sender As Object, ByVal e As EventArgs)
       ''# Crap in here about redirecting WWW
    End Sub

    Protected Sub OnError(ByVal sender As Object, ByVal e As EventArgs)
        ''# crap in here about logging errors
    End Sub




    Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

        ''# MapRoute takes the following parameters, in order:
        ''# (1) Route name
        ''# (2) URL with parameters
        ''# (3) Parameter defaults
        routes.MapRoute( _
            "Default", _
            "{controller}/{action}/{id}", _
            New With { _
                .controller = "Home", _
                .action = "Index", _
                .id = UrlParameter.Optional} _
        )

    End Sub


    Sub Application_Start()
        AreaRegistration.RegisterAllAreas()
        RegisterRoutes(RouteTable.Routes)
    End Sub
End Class

的web.config

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
      <modules runAllManagedModulesForAllRequests="true">
          <add name="_Global" type="UrbanNow.hClassLib.MvcApplication"/>
      </modules>
  </system.webServer>

2 个答案:

答案 0 :(得分:4)

您希望将哪些方面的MVC推入IHttpModule?这种情况的问题是在每个请求上执行IHttpModule,而(主要)使用Global.asax方法来执行首次运行的应用程序配置。你究竟想要实现什么目标?

您可以替代HttpApplication类,并在代码中继承它,因此在您的支持库中,执行以下操作:

public class MyCustomApplication : HttpApplication
{
    public void Application_Start() {

    }
}

并将您的Global.asax.cs类更改为继承自MyCustomApplication而不是HttpApplication。

答案 1 :(得分:0)

我刚刚跑过这个寻找有关同一问题的信息。根本问题是路由模型设计用于HttpApplication类,它基本上是一个自动注册的IHttpHandler实例,带有一些状态voodoo,而不是像我们可以创建并在web.config中注册的IHttpModule。

在我尝试将MVC管道移出主Web项目并进入IHttpModule时,我遇到了多路径注册的问题,因为据我所知,Init()方法有时执行的比一旦进入应用领域。因此,当第二次(或第三次)调用Init()时,RouteTable已经包含了所有内容,并且在尝试注册重复路由期间抛出了异常(在本例中为“默认”默认值)。我不确定是什么导致这种情况,因为我在普通的ASP.NET项目中从未见过它。也许这是MVC特有的东西。

(明显的)解决方案是检查已经注册的路线数量,如果它不是零,则停止:

public void Init(HttpApplication context) {
    if (RouteTable.Routes.Count == 0) {

        RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        RouteTable.Routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
        );
    }
}

这是从添加到默认MVC项目的Global.asax粘贴的股票代码,位于单独程序集中的IHttpModule实现中。

这很有效,但我感觉不到这种爱。为了摆脱Global.asax似乎需要付出很多努力。我仍然需要在这里分离关注点 - 路由逻辑应该存在于一个单独的类中。但是我猜我会使用基于某些配置设置在Global.asax中创建的某种代理模式,并根据正在处理的事件进行调用。

希望这可以帮助用户搜索 mvc MapRoute IHttpModule :)