当会话状态提供程序关闭时,如何在ASP.NET中访问自定义错误页面?

时间:2011-06-23 18:59:37

标签: c# asp.net sql-server session-state

我试图在数据库关闭时在ASP.NET中显示客户错误页面。我使用SQL Server模式来保存会话数据。问题是永远不会调用自定义错误页面。

由于会话数据和数据库位于同一台服务器上,因此不会重定向到自定义错误页面?我猜这个网页应用程序还没有加载?向用户显示会话状态连接失败的堆栈跟踪。

似乎我们需要一些位于初始网站加载之前的东西来检查与数据库的连接。关于如何实现这个的任何想法?

3 个答案:

答案 0 :(得分:1)

将这样的内容添加到您的web.config中?

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
    <error statusCode="403" redirect="NoAccess.htm" />
    <error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>

您可以阅读更多信息here

如果您的SqlSessionState失败,您应该在Application_Error

中的Global.asax事件中处理相应的错误

您可以阅读更多信息here

答案 1 :(得分:1)

我认为错误来自这样一个事实:因为您使用的是内存不足会话状态提供程序(作为数据库),并且数据库连接出现故障,因此Web配置中实际存在感知错误(不在申请中)。我有一个类似的问题,我正在为我的会话状态提供程序使用AppFabric Cache,但是当AppFabric缓存服务关闭时,我得到配置错误页面。

因此,您不能像FlyingStreudel已经建议的那样使用customErrors解决方案,因为它不是应用程序中的错误,而是加载配置。

我四处寻找解决这个问题的方法,但找不到任何方法。我希望这个问题得到解答,这让我对各种错误配置选项感到困惑......

更新:在调查了一段时间之后,看来我的问题来自于SessionStateModule导致AppFabric缓存会话状态提供程序尝试连接到DataCache(这不是可用),并在某处抛出异常(可能是超时)。 因为这发生在HTTP模块的初始化中,似乎无法绕过黄色死亡屏幕

如果原始海报的问题是相同的,我不会感到惊讶 - 在SessionStateModule的初始化中发生与SQL服务器的连接。

答案 2 :(得分:0)

因为错误页面是ASP.NET页面(我可以从您的评论中看到),所以它将在页面生命周期中访问会话数据库。 您必须在Error.aspx页面上设置以下指令,以告诉ASP.Net不要为其加载会话信息:

EnableSessionState="false"

请注意,仅当您在错误页面中不使用任何会话信息时,此方法才有效。

此外,我还如下管理Global.asax页面:

    private static Exception startException;
     protected void Application_Start()
            {
                try
                {
                    AreaRegistration.RegisterAllAreas();
                    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                    RouteConfig.RegisterRoutes(RouteTable.Routes);
                    BundleConfig.RegisterBundles(BundleTable.Bundles);
                    ModelBinders.Binders.Add(typeof(DateTime), new MyDateTimeModelBinder());

                }
                catch (Exception ex)
                {
                    startException = ex;
                }
            }
  static HashSet<string> allowedExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
    ".js", ".css", ".png",".jpg",".jpeg",".gif",".bmp"
};

        public bool IsStaticFile(HttpRequest request)
     {  //My project was a mix of asp.net web forms & mvc so had to write this      
                if (Request.RawUrl.ToLower().Contains("/bundles/") || Request.RawUrl.ToLower().Contains("/frontendcss?") ||
                     Request.RawUrl.ToLower().Contains("/fonts/") 
//these are my css & js bundles. a bit of hack but works for me.
                     )
                {
                return true;
            }
            string fileOnDisk = request.PhysicalPath;
            if (string.IsNullOrEmpty(fileOnDisk))
            {
                return false;
            }

            string extension = Path.GetExtension(fileOnDisk).ToLower();

            return allowedExtensions.Contains(extension);
        }
     protected void Application_BeginRequest()
            {
                if (startException != null && Request.RawUrl.ToLower() == "/Error.aspx".ToLower())
                {
                    return;
                }
                if (startException != null && IsStaticFile(Request))
                {
                    return;
                }

                if (startException != null && Request.RawUrl.ToLower()!= "/Error.aspx".ToLower())
                {
                    //Response.Redirect("Error.aspx");
                    Server.Transfer("Error.aspx");
                    this.Context.AddError(startException);                
                    return;
                }


            }
        protected void Application_Error(object sender, EventArgs e)
                {
                   Exception exception = Server.GetLastError();
                     Response.Clear();
                    Server.ClearError(); 
                   Server.Transfer("Error.aspx");     
                }