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:对用户与服务器端始终显示详细出错信息。
posted @ 2016-01-29 13:55  可可味  阅读(1908)  评论(0编辑  收藏  举报