zoukankan      html  css  js  c++  java
  • Application_Error异常处理 自定义错误页

    在Global.asax文件中定义该方法
    /// <summary>
      /// 错误异常
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      protected void Application_Error(Object sender, EventArgs e)
      {
       HttpContext content = HttpContext.Current;
       Exception ex = content.Server.GetLastError().GetBaseException();
       if (ex.GetType().Name.Equals("HttpException"))
       {
        HttpException httpEx = (HttpException)ex;
        int httpCode = httpEx.GetHttpCode();
        if (httpCode == 404)
        {
         Response.StatusCode = 404;
         //跳转到指定的静态404信息页面,根据需求自己更改URL
         Response.WriteFile("~/Views/Error/404.html");
         Server.ClearError();
         return;
        }
       }
       /*-----------------------------------------------------
        * 此处代码可根据需求进行日志记录,或者处理其他业务流程
        * ---------------------------------------------------*/
       new Handling(content).SaveCatch();
       /*
        * 跳转到指定的http 500错误信息页面
        * 跳转到静态页面一定要用Response.WriteFile方法                
        */
       Response.StatusCode = 500;
       Response.WriteFile("~/Views/Error/500.html");
       //一定要调用Server.ClearError()否则会触发错误详情页(就是黄页)
       Server.ClearError();
      }

    定义异常处理工具类

    //==========================获取异常信息==============================================
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web;
    using Dapper;
    
    namespace LionCN.Models.Repository.ExceptionHandling
    {
    public class Handling
    {
    public readonly static string sqlCmdSessID = "__sqlCmdSessID";
    /// <summary> 连接字符串 </summary>
    private string ExecptionConnString = ConfigurationManager.ConnectionStrings["ErrorConnString"].ToString();
    private HttpContext content = null;
    private HttpRequest Request = null;
    
    #region 构造函数
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="content">上下文</param>
    public Handling(HttpContext content)
    {
    this.content = content;
    this.Request = content.Request;
    }
    #endregion
    
    #region 连接数据库
    /// <summary>
    /// 连接数据库
    /// </summary>
    /// <returns></returns>
    public SqlConnection GetSqlConnection()
    {
    SqlConnection conn = new SqlConnection(ExecptionConnString);
    conn.Open();
    return conn;
    }
    #endregion
    
    public static void saveSqlStr(string sqlStr)
    {
    if (HttpContext.Current != null && HttpContext.Current.Session!=null)
    {
    HttpContext.Current.Session[sqlCmdSessID] = sqlStr;
    
    }
    }
    
    /// <summary>
    /// 保存异常
    /// </summary>
    public void SaveCatch()
    {
    //获取当前时间
    string dateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
    //当前异常
    Exception lastError = content.Server.GetLastError();
    string WebSite="cnB2C";
    
    //服务器端异常
    var httpExcetion = lastError as HttpException ?? new HttpException(500, lastError.Message, lastError);
    //客户端请求方式
    string methodType = Request.HttpMethod;
    //错误代码
    int HttpCode = httpExcetion.GetHttpCode();
    //返回接受请求的服务器地址
    string iisLocalAddr = Request.ServerVariables["LOCAL_ADDR"];
    //服务器名称
    string ServerName = string.Format("IIS_{0}", iisLocalAddr);
    //获取当前请求的URL页面
    string ErrorPage = Request.Url != null ? Request.Url.ToString() : string.Empty;
    //捕获的错误信息
    string errMessage = content.Server.HtmlEncode(lastError.Message);
    //获取堆栈上直接帧的字符串表示形式
    string errStackTrace = content.Server.HtmlEncode(lastError.StackTrace);
    //获取引发当前异常的方法
    string errTargetSite = lastError.TargetSite.ToString();
    //获取错误详情
    string errDescription = String.Format("<b>Message:</b>{0}<br/>{4}<b>HelpLink:</b>{1}<br/>{4}<b>StackTrace:</b>{2}<br/>{4}<b>TargetSite:</b>{3}{4}", errMessage, lastError.HelpLink, errStackTrace, errTargetSite, Environment.NewLine);
    //获取连接来路完整地址
    string RefererPage = Request.ServerVariables["HTTP_REFERER"];
    //获取客户端IP
    string RemotrIP = Request.UserHostAddress;
    //检查浏览页面的访问者在用什么操作系统(包括版本号)浏览器(包括版本号)和用户个人偏好的代码
    string browser = Request.ServerVariables["HTTP_USER_AGENT"];
    
    string sqlCmdStr = content.Session != null && content.Session[sqlCmdSessID] != null ? content.Session[sqlCmdSessID].ToString() : string.Empty;
    
    //获取cookie
    string rCookie = string.Empty;
    //获取表单
    StringBuilder rForm = new StringBuilder();
    //获取session
    StringBuilder rSession = new StringBuilder();
    if (content != null)
    {
    rCookie = string.IsNullOrWhiteSpace(Request.ServerVariables["HTTP_COOKIE"]) ? string.Empty : Request.ServerVariables["HTTP_COOKIE"];
    if (Request != null && Request.Form != null)
    {
    var FormCollection = Request.Form;
    foreach (string key in FormCollection.Keys)
    {
    rForm.Append(key + ":" + FormCollection[key] + ";");
    }
    }
    if (content.Session != null)
    {
    foreach (string key in content.Session.Keys)
    {
    rSession.Append(key + ":" + (content.Session[key] == null ? string.Empty : content.Session[key]) + ";");
    }
    }
    }
    DynamicParameters dbParameters = new DynamicParameters();
    dbParameters.Add("@WebSite",WebSite);
    dbParameters.Add("@ServerName", ServerName);
    dbParameters.Add("@HttpCode",HttpCode);
    dbParameters.Add("@ErrorPage",ErrorPage);
    dbParameters.Add("@errMessage", errMessage);
    dbParameters.Add("@errStackTrace", errStackTrace);
    dbParameters.Add("@errTargetSite",errTargetSite);
    dbParameters.Add("@errDescription",errDescription);
    dbParameters.Add("@RefererPage",RefererPage);
    dbParameters.Add("@RemotrIP",RemotrIP);
    dbParameters.Add("@browser",browser);
    dbParameters.Add("@sqlCmd",sqlCmdStr);
    dbParameters.Add("@requestCookie",rCookie.ToString());
    dbParameters.Add("@requestSession",rSession.ToString());
    dbParameters.Add("@requestForm", rForm.ToString());
    dbParameters.Add("@errTime", dateTime);
    dbParameters.Add("methodType", methodType);
    
    //保存异常信息到数据库中
    string sqlStr = @"
    INSERT INTO [LionCN_WebErrorLog].[dbo].[WebErrorLog]
       ([WebSite]
       ,[ServerName]
       ,[HttpCode]
       ,[ErrorPage]
       ,[errMessage]
       ,[errStackTrace]
       ,[errTargetSite]
       ,[errDescription]
       ,[RefererPage]
       ,[RemotrIP]
       ,[browser]
       ,[sqlCmd]
       ,[requestCookie]
       ,[requestSession]
       ,[requestForm]
       ,[errTime]
       ,[methodType])
     VALUES
       (@WebSite
       ,@ServerName
       ,@HttpCode
       ,@ErrorPage
       ,@errMessage
       ,@errStackTrace
       ,@errTargetSite
       ,@errDescription
       ,@RefererPage
       ,@RemotrIP
       ,@browser
       ,@sqlCmd
       ,@requestCookie
       ,@requestSession
       ,@requestForm
       ,@errTime
       ,@methodType)
    ";
    
    using (IDbConnection conn =this.GetSqlConnection())
    {
    
    conn.Execute(sqlStr,dbParameters);
    }
    
    }
    
    }
    }
    ====================自定义错误页===================================
    1、打开webconfig配置如下节点
     
    <customErrors mode="Off" />
     
    <system.webServer>
     <httpErrors  errorMode="Custom" existingResponse="Auto">
                <remove statusCode="404" subStatusCode="-1" />
                <error statusCode="404" prefixLanguageFilePath="" path="/Error/404.htm" responseMode="ExecuteURL" />
      </httpErrors>
     </system.webServer>

     节点解释

    ExistingResponse:建议选用Replace

    ExistingResponse属性开关在httpErrors中 (属于asp.net报错)。这个开关是决定谁来抛出异常,它有三个模式

    • Auto 默认错误页面 Asp.net或IIS
    • Replace 强制IIS
    • PassThrough 强制Asp.net 

    由于我们为了安全因素的考虑。通常的配置需要把程序级开发报错页面对内显示,对外则用友好的报错页面。

    我们需要用到Replace强制IIS报错,这样可以解决对外抛出详细的.Net开发报错页面。只有当要查找问题时

    才调到 PassThrough模式,打开.net错误页面。

    <httpErrors errorMode="Detailed" />项,而虚拟主机控制面板又可以自定义404,只要把errorMode的值修改为Custom即可。
    在这里说明下:
    errorMode有三个值,建议选用DetailedLocalOnly

      • Custom:对用户与服务器端始终显示自定义页面
      • DetailedLocalOnly:只能服务器端显示详细出错信息
      • Detailed:对用户与服务器端始终显示详细出错信息。
  • 相关阅读:
    R语言:随机抽样(sample函数)
    SNP (Single Nucleotide Polymorphism), SNV ( single nucleotide variants ) , Indel (insertion-deletion) 的区别
    剑指offer五十六之删除链表中重复的结点
    剑指offer五十五之链表中环的入口结点
    剑指offer五十四之字符流中第一个不重复的字符
    剑指offer五十三之表示数值的字符串
    剑指offer五十二之正则表达式匹配
    剑指offer五十一之构建乘积数组
    求游戏晋级花费的宝石的期望
    剑指offer五十一之构建乘积数组
  • 原文地址:https://www.cnblogs.com/zhangweidong/p/5168796.html
Copyright © 2011-2022 走看看