在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:对用户与服务器端始终显示详细出错信息。