我已经成功创建了一个iHttpModule来替换许多Web窗体应用程序中的Global.asax文件。但是在查看我的MVC应用程序中的Global.asax文件时,方法完全不同。
我想知道是否仍然可以在MVC应用程序中创建相同的东西。我知道没有必要,Global.asax工作得很好。我想我只想在我的应用程序的根目录中只有web.config。
另外,我将所有类放在一个单独的类库项目中,而不是放在我的MVC应用程序中的文件夹中。不确定这是否有所作为。
这是我目前所拥有的,但不幸的是我的路线没有注册
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
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="_Global" type="UrbanNow.hClassLib.MvcApplication"/>
</modules>
</system.webServer>
答案 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 :)