为什么我的主机(softsyshosting.com)不支持BeginRequest和EndRequest事件处理程序?

9

我听说Softsys Hosting非常好,所以我决定将我的ASP.NET MVC解决方案迁移到他们的平台上。但是它无法在他们的平台上运行。我能够确定问题出在我的BeginRequest事件处理程序上。如果我有这些处理程序,就会出现错误。以下是我的代码:

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    this.BeginRequest += new EventHandler(MvcApplication_BeginRequest);
    this.EndRequest += new EventHandler(MvcApplication_EndRequest);
} 

void MvcApplication_EndRequest(object sender, EventArgs e) 
{
}

void MvcApplication_BeginRequest(object sender, EventArgs e) 
{
}

我可以通过创建默认的ASP.NET MVC应用程序并添加上述代码来重现此问题。奇怪的是,这段代码在我的旧主机上运行良好,但只会在我的新(共享)主机上崩溃。如果我在代码中有这些事件处理程序,我就会得到以下错误:
服务器错误在'/'应用程序。
对象引用未设置为对象实例。说明:在当前网络请求执行期间发生未处理的异常。请查看堆栈跟踪以获取有关错误的更多信息以及错误在代码中的源和位置的信息。
异常详细信息:System.NullReferenceException: 对象引用未设置为对象实例。
源错误:在当前网络请求执行期间生成了一个未处理的异常。可以使用下面的异常堆栈跟踪标识异常的起源和位置。
堆栈跟踪:
[NullReferenceException: 对象引用未设置为对象实例。] System.Web.PipelineModuleStepContainer.GetStepArray(RequestNotification notification, Boolean isPostEvent) +27 System.Web.PipelineModuleStepContainer.GetEventCount(RequestNotification notification, Boolean isPostEvent) +11 System.Web.PipelineStepManager.ResumeSteps(Exception error) +205 System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) +91 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +514
我尝试与Softsys进行故障排除,但他们没有提供太多帮助,基本上只确认我已经在我的管理员控制面板中打开了“ASP.NET Pipeline (MVC)”功能。
有人能:
1.告诉我是否编写了错误的代码 2.向我展示解决方法 3.解释为什么在一个主机上出现此错误而在另一个主机上没有。

这是否更适合向您的主机支持团队提出问题呢? - Oliver Hanappi
你有没有偶然使用 NHibernate? - Andreas Grech
Oliver,是的,我尝试过向Softsys Hosting寻求支持,但他们并没有提供太多帮助。他们想要收取我每小时95美元的费用来解决这个问题。除此之外,我对他们的一切都很满意,如果是我自己的问题,我不想放弃他们。Dreas,我没有使用NHibernate。 - Whozumommy
2个回答

16

你需要在每个HttpApplication实例中注册处理程序。可能有多个HttpApplication实例。对于IIS 6和IIS 7 classic模式,只有在第一次请求时才会调用Application_Start(对于IIS 7集成模式,则在Web应用程序启动之前,在任何请求之前)。所以为了让所有东西都正常工作,你需要在HttpApplication的重写Init方法或构造函数中添加事件处理程序。如果你将它们添加到构造函数中,这些处理程序将首先被调用,甚至在已注册模块的处理程序之前。
因此,你的代码应该像这样:

public class MySmartApp: HttpApplication{
    public override void Init(){
        this.BeginRequest += new EventHandler(MvcApplication_BeginRequest);
        this.EndRequest += new EventHandler(MvcApplication_EndRequest);
    }
    protected void Application_Start(){
        RegisterRoutes(RouteTable.Routes);
    } 
}
或者像这样:
public class MySmartApp: HttpApplication{
    public MySmartApp(){
        this.BeginRequest += new EventHandler(MvcApplication_BeginRequest);
        this.EndRequest += new EventHandler(MvcApplication_EndRequest);
    }
    protected void Application_Start(){
        RegisterRoutes(RouteTable.Routes);
    } 
}

这是很棒的信息,但我怀疑它不能解决这个问题。我可以重现这个问题(尽管对我来说只是偶尔发生),而不需要在Application_OnStart中注册处理程序。弄清楚这个错误实际上意味着什么(哪些内容为空)将会很有用。 - Tom Lianza
你能提供一些关于上述信息的链接吗?也许是MSDN文章? - Jiho Han
很棒的答案。对我解决了问题。这是在.NET 4.5、MVC 4、IIS 8上的。 - Jeff Sharp
好的,这个可以工作,并且文档(msdn.microsoft.com/en-us/library/bb470252%28v=vs.100%29.aspx)确实说“在IIS 7.0中的集成模式下,必须在模块的Init方法中注册事件处理程序。”但我想我没有看到它——如果在一个池的一个实例中挂钩事件,而在其他实例中没有挂钩事件,怎么会导致空引用异常?显然,如果您不在任何一个实例中挂钩事件,就不会发生任何问题。 - user1454265

7
我看您是从IIS 6或IIS 7经典模式切换到了IIS 7集成模式。在IIS 7集成模式下,请求处理与应用程序启动解耦。这篇文章解释了其中的原因和目的。

要修复它,您需要将代码移动到Application_BeginRequest中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接