ASP.NET 2.0 : Best Practice for writing Error Page

前端 未结 2 1758
执笔经年
执笔经年 2020-12-13 07:41

In asp.net 2.0 web site, what is the best way of writing Error page. I have seen following section at following location:

  • Web.Config

    
    
            
  • 2条回答
    •  我在风中等你
      2020-12-13 08:22

      BigBlondeViking's response worked great for me except that I found it did not process 403's (which ASP generates when you try to directly access the /Scripts/ or /Content/ directories.) It appears that this is not propegated as an exception and thus not trappable in the Application_Error handling. (this was identified as a "security vulnerability" by an external firm - don't get me started on that!)

      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
              }
          }
      }
      

      I also made a minor change in my common Error Handling. As we are using ASP.NET MVC, I wanted to explicitly call into a controller, as well as pass the exception object. This allowed me to access the exception itself so that I can log / send detailed e-mail depending on the code;

      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);
      }
      

      In order to pass the exception OBJECT (not just the message and code) I explicitly invoked the controller:

      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);
      }
      

    提交回复
    热议问题