ASP.NET 2.0:书写错误页面最佳实践(ASP.NET 2.0 : Best Practice

2019-06-27 20:01发布

在asp.net 2.0的网站,什么是写入错误页面的最佳途径。 我已经看到了以下的以下位置部分:

  • Web.Config中

    <customErrors mode="RemoteOnly" defaultRedirect="~/Pages/Common/DefaultRedirectErrorPage.aspx">
    

  • Global.asax中

    void Application_Error(object sender, EventArgs e) 
    { 
    }
    

  • 我没有得到如何以最好的方式进行错误处理使用这两者。

    请指引我最好的办法。

    Answer 1:

    在我的全球ASAX我经常检查,看看它是什么类型的HTTP错误的...

    然后转移到在web.config中指定了正确的错误页面,我喜欢来处理通常的嫌疑人,404(丢失页)和500(服务器错误)

    HTTP状态代码的一些背景是importaint知道为什么他们的处理方式:

    http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

    我的web.config是这个样子

    <customErrors mode="On"  defaultRedirect="~/error.aspx"  >
      <error statusCode="404" redirect="~/lost.aspx"  />
      <error statusCode="500" redirect="~/error.aspx"  />
    </customErrors>
    

    我失去的页面有逻辑,它试图找到一个链接,他们可能一直在寻找的页面,以及一些其他格式。

    我的错误页面是一个有点不同,呈现出一些错误信息,

    所以我同时处理不同。

    取决于如果您有担保您的网站,你可能要处理401/403的领域?

    protected void Application_Error(object sender, EventArgs e)
    {
        var context = Context;
    
    
        var error = context.Server.GetLastError() as HttpException;
        var statusCode = error.GetHttpCode().ToString();
    
        // we can still use the web.config custom errors information to
        // decide whether to redirect
        var config = (CustomErrorsSection)WebConfigurationManager.GetSection("system.web/customErrors");
        if (config.Mode == CustomErrorsMode.On ||
            (config.Mode == CustomErrorsMode.RemoteOnly && context.Request.Url.Host != "localhost"))
        {
            // set the response status code
            context.Response.StatusCode = error.GetHttpCode();
    
            // Server.Transfer to correct ASPX file for error
            if (config.Errors[statusCode] != null)
            {
    
                HttpContext.Current.Server.Transfer(config.Errors[statusCode].Redirect);
            }
            else
                HttpContext.Current.Server.Transfer(config.DefaultRedirect);
        }
    }
    

    我之所以服务器传递这样搜索引擎就不会感到困惑,并让我的网站管理员日志有意义...如果你重定向你返回一个HTTP状态302告诉浏览器去重定向到网页...那么这下一页返回状态代码200(OK)。

    302 - > 200,甚至302 - > 404具有不同的含义,只是一个404 ...

    然后说我的404错误页面我要确保我设置的HTTP错误的状态代码:

    protected void Page_PreRender(object sender, EventArgs e)
    {
        Response.Status = "404 Lost";
        Response.StatusCode = 404;
    
    }
    

    这篇文章是对我很有帮助,我知道我想做的事,但我喜欢这个代码是如何看的web.config设置... http://helephant.com/2009/02/improving-the-way-aspnet-手柄-404-请求/

    返回正确的状态码

    默认情况下,处理一个404错误页面的页面不返回404个状态码给浏览器。 它显示了你的用户提供的,但没有任何额外的信息来标记的页面为错误页面的错误消息。

    这就是所谓的软404软404页都不如那些返回404个状态码,因为返回404个状态码可以让任何访问您的文件,该页面是一个错误页面,而不是你的网站的真实页为好。 因为那样的话,他们知道自己应该从索引中删除死页让用户不会遵循结果页面的死链接到你的网站,这是搜索引擎最有用。

    返回404个状态码页面也进行错误检测有用的,因为他们会在你的服务器日志记录,所以如果你有意想不到的404错误,他们就会很容易找到。 下面是谷歌网站管理员工具的404错误报告的一个例子:

    EDITS

    难道需要写server.clearerror()在Global.asax中? 是什么影响

    • 不,你可以做你的错误页面,不知道有什么影响? 如果你做一个转让非,如果你重定向,有可能是在请求之间发生了另一个错误的可能性? 我不知道

    为什么在web.config中,我们应该写error.aspx两次用一个状态代码500,另一个是的defaultRedirect

    • 我用2,因为丢失的页面应该显示/,比一台服务器的错误做不同的事情。 错误页面显示用户有我们无法恢复的错误...和它可能是我们的错。 我离开默认重定向任何其他错误代码为好。 403401,400(它们是较为少见的,但应办理)

    你也可以告诉我error.aspx和lost.aspx的代码。

    • 这取决于你的网站的类型。 你得到了错误的方式相同,但你用它做什么是由你。 我丢失的页面我寻找一些内容的用户可能一直在寻找。 错误页面我记录错误等用户友好哎呀页面......你需要找出所需要的。


    Answer 2:

    BigBlondeViking的回应,只是对我来说真是棒极了,我发现它没有处理403的(这ASP当您尝试直接访问/脚本/或/内容/目录。产生)看来,这不是propegated作为例外,因而不捕获的在处理的Application_Error。 (这被确定为“安全漏洞”,由外部公司 - 不要让我开始对!)

    protected void Application_PostRequestHandlerExecute(object sender, EventArgs e)
    {
        if (!Context.Items.Contains("HasHandledAnError")) // have we alread processed?
        {
            if (Response.StatusCode > 400 &&  // any error
                Response.StatusCode != 401)   // raised when login is required
            {
                Exception exception = Server.GetLastError();    // this is null if an ASP error
                if (exception == null)
                {
                    exception = new HttpException((int)Response.StatusCode, HttpWorkerRequest.GetStatusDescription(Response.StatusCode));
                }
                HandleRequestError(exception); // code shared with Application_Error
            }
        }
    }
    

    我也改变了我的常见错误处理的微小变化。 由于我们使用ASP.NET MVC,我想明确地调用到控制器,以及传递异常对象。 这让我访问例外本身,这样我就可以登录/发送取决于代码的详细的电子邮件;

    public ActionResult ServerError(Exception exception)
    {
        HttpException httpException = exception as HttpException;
        if(httpException != null)
        {
            switch (httpException.GetHttpCode())
            {
                case 403:
                case 404:
                    Response.StatusCode = 404;
                    break;
            }
            // no email...
            return View("HttpError", httpException);
        }
        SendExceptionMail(exception);
        Response.StatusCode = 500;
        return View("ServerError", exception);
    }
    

    为了通过异常对象(不只是消息和代码)我显式调用控制器:

    protected void HandleRequestError(Exception exception)
    {
        if (Context.Items.Contains("HasHandledAnError"))
        {
            // already processed
            return;
        }
        // mark as processed.
        this.Context.Items.Add("HasHandledAnError", true);
    
        CustomErrorsSection customErrorsSection = WebConfigurationManager.GetWebApplicationSection("system.web/customErrors") as CustomErrorsSection;
    
        // Do not show the custom errors if
        // a) CustomErrors mode == "off" or not set.
        // b) Mode == RemoteOnly and we are on our local development machine.
        if (customErrorsSection == null || !Context.IsCustomErrorEnabled ||
            (customErrorsSection.Mode == CustomErrorsMode.RemoteOnly && Request.IsLocal))
        {
            return;
        }
    
        int httpStatusCode = 500;   // by default.
        HttpException httpException = exception as HttpException;
        if (httpException != null)
        {
            httpStatusCode = httpException.GetHttpCode();
        }
    
        string viewPath = customErrorsSection.DefaultRedirect;
        if (customErrorsSection.Errors != null)
        {
            CustomError customError = customErrorsSection.Errors[((int)httpStatusCode).ToString()];
            if (customError != null && string.IsNullOrEmpty(customError.Redirect))
            {
                viewPath = customError.Redirect;
            }
        }
    
        if (string.IsNullOrEmpty(viewPath))
        {
            return;
        }
    
        Response.Clear();
        Server.ClearError();
    
        var httpContextMock = new HttpContextWrapper(Context);
        httpContextMock.RewritePath(viewPath);
        RouteData routeData = RouteTable.Routes.GetRouteData(httpContextMock);
        if (routeData == null)
        {
            throw new InvalidOperationException(String.Format("Did not find custom view with the name '{0}'", viewPath));
        }
        string controllerName = routeData.Values["controller"] as string;
        if (String.IsNullOrEmpty(controllerName))
        {
            throw new InvalidOperationException(String.Format("No Controller was found for route '{0}'", viewPath));
        }
        routeData.Values["exception"] = exception;
    
        Response.TrySkipIisCustomErrors = true;
        RequestContext requestContext = new RequestContext(httpContextMock, routeData);
        IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
        IController errorsController = factory.CreateController(requestContext, controllerName);
        errorsController.Execute(requestContext);
    }
    


    文章来源: ASP.NET 2.0 : Best Practice for writing Error Page