运维开发网

自定义MVC异常过滤器的用例

运维开发网 https://www.qedev.com 2022-07-08 23:01 出处:网络
在上一篇文章中,解释了用户定义的异常过滤器。本文将结合工作中的真实案例解释如何使用自定义异常过滤器。


在上一篇文章中,解释了用户定义的异常过滤器。本文将结合工作中的真实案例解释如何使用自定义异常过滤器。


一、需求

这种情况下要实现的功能需求:记录异常发生时的日志,日志内容包括控制者名称、动作名称、使用的浏览器类型和版本等。


二、案例


1、创建工具类

首先,创建要在项目中使用的工具类。


1.1、创建日志工具类

Log4net用于记录案例中的日志。要先添加对Log4net的引用,直接在NuGet中搜索Log4net,然后安装。

消息实体类代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace MVCCuetomerExcepFilterDemo.Models{ /// lt;summarygt; /// 日志消息实体类 /// lt;/summarygt; public class LogMessageEntity { /// lt;summarygt; /// 操作时间 /// lt;/summarygt; public DateTime OperationTime { get; set; } /// lt;summarygt; /// Url地址 /// lt;/summarygt; public string Url { get; set; } /// lt;summarygt; /// 类名 /// lt;/summarygt; public string Class { get; set; } /// lt;summarygt; /// IP /// lt;/summarygt; public string Ip { get; set; } /// lt;summarygt; /// 主机 /// lt;/summarygt; public string Host { get; set; } /// lt;summarygt; /// 浏览器 /// lt;/summarygt; public string Browser { get; set; } /// lt;summarygt; /// 操作人 /// lt;/summarygt; public string UserName { get; set; } /// lt;summarygt; /// 内容 /// lt;/summarygt; public string Content { get; set; } /// lt;summarygt; /// 异常信息 /// lt;/summarygt; public string ExceptionInfo { get; set; } /// lt;summarygt; /// 异常来源 /// lt;/summarygt; public string ExceptionSource { get; set; } /// lt;summarygt; /// 异常信息备注 /// lt;/summarygt; public string ExceptionRemark { get; set; } }}

创建日志级别枚举类型,分别对应Log4net中的日志级别,代码如下:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Web;namespace MVCCuetomerExcepFilterDemo.Models.Enums{ /// lt;summarygt; /// 日志级别 /// lt;/summarygt; public enum LogLevel { /// lt;summarygt; /// 错误 /// lt;/summarygt; [Description("错误")] Error, /// lt;summarygt; /// 警告 /// lt;/summarygt; [Description("警告")] Warning, /// lt;summarygt; /// 信息 /// lt;/summarygt; [Description("信息")] Info, /// lt;summarygt; /// 调试 /// lt;/summarygt; [Description("调试")] Debug }}

使用以下代码创建一个格式化日志格式的类:

using MVCCuetomerExcepFilterDemo.Models;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web;namespace MVCCuetomerExcepFilterDemo.Util{ /// lt;summarygt; /// 日志格式器 /// lt;/summarygt; public class LogFormat { /// lt;summarygt; /// 生成错误 /// lt;/summarygt; /// lt;param name="logMessage"gt;对象lt;/paramgt; /// lt;returnsgt;lt;/returnsgt; public string ErrorFormat(LogMessageEntity logMessage) { StringBuilder strInfo = new StringBuilder(); strInfo.Append("1. 错误: gt;gt; 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n"); strInfo.Append("2. 地址: " + logMessage.Url + " \r\n"); strInfo.Append("3. 类名: " + logMessage.Class + " \r\n"); strInfo.Append("4. Ip : " + logMessage.Ip + " 主机: " + logMessage.Host + " 浏览器: " + logMessage.Browser + " \r\n"); strInfo.Append("5. 内容: " + logMessage.Content + "\r\n"); strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n"); return strInfo.ToString(); } /// lt;summarygt; /// 生成警告 /// lt;/summarygt; /// lt;param name="logMessage"gt;对象lt;/paramgt; /// lt;returnsgt;lt;/returnsgt; public string WarnFormat(LogMessageEntity logMessage) { StringBuilder strInfo = new StringBuilder(); strInfo.Append("1. 警告: gt;gt; 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n"); strInfo.Append("2. 地址: " + logMessage.Url + " \r\n"); strInfo.Append("3. 类名: " + logMessage.Class + " \r\n"); strInfo.Append("4. Ip : " + logMessage.Ip + " 主机: " + logMessage.Host + " 浏览器: " + logMessage.Browser + " \r\n"); strInfo.Append("5. 内容: " + logMessage.Content + "\r\n"); strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n"); return strInfo.ToString(); } /// lt;summarygt; /// 生成信息 /// lt;/summarygt; /// lt;param name="logMessage"gt;对象lt;/paramgt; /// lt;returnsgt;lt;/returnsgt; public string InfoFormat(LogMessageEntity logMessage) { StringBuilder strInfo = new StringBuilder(); strInfo.Append("1. 信息: gt;gt; 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n"); strInfo.Append("2. 地址: " + logMessage.Url + " \r\n"); strInfo.Append("3. 类名: " + logMessage.Class + " \r\n"); strInfo.Append("4. Ip : " + logMessage.Ip + " 主机: " + logMessage.Host + " 浏览器: " + logMessage.Browser + " \r\n"); strInfo.Append("5. 内容: " + logMessage.Content + "\r\n"); strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n"); return strInfo.ToString(); } /// lt;summarygt; /// 生成调试 /// lt;/summarygt; /// lt;param name="logMessage"gt;对象lt;/paramgt; /// lt;returnsgt;lt;/returnsgt; public string DebugFormat(LogMessageEntity logMessage) { StringBuilder strInfo = new StringBuilder(); strInfo.Append("1. 调试: gt;gt; 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n"); strInfo.Append("2. 地址: " + logMessage.Url + " \r\n"); strInfo.Append("3. 类名: " + logMessage.Class + " \r\n"); strInfo.Append("4. Ip : " + logMessage.Ip + " 主机: " + logMessage.Host + " 浏览器: " + logMessage.Browser + " \r\n"); strInfo.Append("5. 内容: " + logMessage.Content + "\r\n"); strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n"); return strInfo.ToString(); } /// lt;summarygt; /// 生成异常信息 /// lt;/summarygt; /// lt;param name="logMessage"gt;对象lt;/paramgt; /// lt;returnsgt;lt;/returnsgt; public string ExceptionFormat(LogMessageEntity logMessage) { StringBuilder strInfo = new StringBuilder(); strInfo.Append("1. 调试: gt;gt; 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n"); strInfo.Append("2. 地址: " + logMessage.Url + " \r\n"); strInfo.Append("3. 类名: " + logMessage.Class + " \r\n"); strInfo.Append("4. 主机: " + logMessage.Host + " Ip : " + logMessage.Ip + " 浏览器: " + logMessage.Browser + " \r\n"); strInfo.Append("5. 异常: " + logMessage.ExceptionInfo + "\r\n"); //strInfo.Append("6. 来源: " + logMessage.ExceptionSource + "\r\n"); //strInfo.Append("7. 实例: " + logMessage.ExceptionRemark + "\r\n"); strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n"); return strInfo.ToString(); } }}

使用以下代码创建一个日志类:

using log4net;using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace MVCCuetomerExcepFilterDemo.Util{ /// lt;summarygt; /// 日志 /// lt;/summarygt; public class Log { private ILog logger; public Log(ILog log) { this.logger = log; } public void Debug(object message) { this.logger.Debug(message); } public void Error(object message) { this.logger.Error(message); } public void Info(object message) { this.logger.Info(message); } public void Warn(object message) { this.logger.Warn(message); } }}

使用以下代码创建日志初始化类:

using log4net;using MVCCuetomerExcepFilterDemo.Models;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Web;namespace MVCCuetomerExcepFilterDemo.Util{ /// lt;summarygt; /// 日志初始化 /// lt;/summarygt; public class LogFactory { static LogFactory() { FileInfo configFile = new FileInfo(HttpContext.Current.Server.MapPath("/XmlConfig/log4net.config")); log4net.Config.XmlConfigurator.Configure(configFile); } public static Log GetLogger(Type type) { return new Log(LogManager.GetLogger(type)); } public static Log GetLogger(string str) { return new Log(LogManager.GetLogger(str)); } }}

最后,添加log4net的配置文件:

lt;xml version="1.0" encoding="utf-8" gt;lt;configurationgt; lt;configSectionsgt; lt;section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/gt; lt;/configSectionsgt; lt;log4netgt; lt;!--根配置--gt; lt;rootgt; lt;!--日志级别:可选值: ERROR gt; WARN gt; INFO gt; DEBUG --gt; lt;level value="ERROR"/gt; lt;level value="WARN"/gt; lt;level value="INFO"/gt; lt;level value="DEBUG"/gt; lt;appender-ref ref="ErrorLog" /gt; lt;appender-ref ref="WarnLog" /gt; lt;appender-ref ref="InfoLog" /gt; lt;appender-ref ref="DebugLog" /gt; lt;/rootgt; lt;!-- 错误 Error.log--gt; lt;appender name="ErrorLog" type="log4net.Appender.RollingFileAppender"gt; lt;!--目录路径,可以是相对路径或绝对路径--gt; lt;param name="File" value="D:\log"/gt; lt;!--文件名,按日期生成文件夹--gt; lt;param name="DatePattern" value="/yyyy-MM-dd/amp;quot;Error.logamp;quot;"/gt; lt;!--追加到文件--gt; lt;appendToFile value="true"/gt; lt;!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--gt; lt;rollingStyle value="Composite"/gt; lt;!--写到一个文件--gt; lt;staticLogFileName value="false"/gt; lt;!--单个文件大小。单位:KB|MB|GB--gt; lt;maximumFileSize value="200MB"/gt; lt;!--最多保留的文件数,设为"-1"则不限--gt; lt;maxSizeRollBackups value="-1"/gt; lt;!--日志格式--gt; lt;layout type="log4net.Layout.PatternLayout"gt; lt;conversionPattern value="%message"/gt; lt;/layoutgt; lt;filter type="log4net.Filter.LevelRangeFilter"gt; lt;param name="LevelMin" value="ERROR" /gt; lt;param name="LevelMax" value="ERROR" /gt; lt;/filtergt; lt;/appendergt; lt;!-- 警告 Warn.log--gt; lt;appender name="WarnLog" type="log4net.Appender.RollingFileAppender"gt; lt;!--目录路径,可以是相对路径或绝对路径--gt; lt;param name="File" value="D:\log"/gt; lt;!--文件名,按日期生成文件夹--gt; lt;param name="DatePattern" value="/yyyy-MM-dd/amp;quot;Warn.logamp;quot;"/gt; lt;!--追加到文件--gt; lt;appendToFile value="true"/gt; lt;!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--gt; lt;rollingStyle value="Composite"/gt; lt;!--写到一个文件--gt; lt;staticLogFileName value="false"/gt; lt;!--单个文件大小。单位:KB|MB|GB--gt; lt;maximumFileSize value="200MB"/gt; lt;!--最多保留的文件数,设为"-1"则不限--gt; lt;maxSizeRollBackups value="-1"/gt; lt;!--日志格式--gt; lt;layout type="log4net.Layout.PatternLayout"gt; lt;conversionPattern value="%message"/gt; lt;/layoutgt; lt;filter type="log4net.Filter.LevelRangeFilter"gt; lt;param name="LevelMin" value="WARN" /gt; lt;param name="LevelMax" value="WARN" /gt; lt;/filtergt; lt;/appendergt; lt;!-- 信息 Info.log--gt; lt;appender name="InfoLog" type="log4net.Appender.RollingFileAppender"gt; lt;!--目录路径,可以是相对路径或绝对路径--gt; lt;param name="File" value="D:\log"/gt; lt;!--文件名,按日期生成文件夹--gt; lt;param name="DatePattern" value="/yyyy-MM-dd/amp;quot;Info.logamp;quot;"/gt; lt;!--追加到文件--gt; lt;appendToFile value="true"/gt; lt;!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--gt; lt;rollingStyle value="Composite"/gt; lt;!--写到一个文件--gt; lt;staticLogFileName value="false"/gt; lt;!--单个文件大小。单位:KB|MB|GB--gt; lt;maximumFileSize value="200MB"/gt; lt;!--最多保留的文件数,设为"-1"则不限--gt; lt;maxSizeRollBackups value="-1"/gt; lt;!--日志格式--gt; lt;layout type="log4net.Layout.PatternLayout"gt; lt;conversionPattern value="%message"/gt; lt;/layoutgt; lt;filter type="log4net.Filter.LevelRangeFilter"gt; lt;param name="LevelMin" value="INFO" /gt; lt;param name="LevelMax" value="INFO" /gt; lt;/filtergt; lt;/appendergt; lt;!-- 调试 Debug.log--gt; lt;appender name="DebugLog" type="log4net.Appender.RollingFileAppender"gt; lt;!--目录路径,可以是相对路径或绝对路径--gt; lt;param name="File" value="D:\log"/gt; lt;!--文件名,按日期生成文件夹--gt; lt;param name="DatePattern" value="/yyyy-MM-dd/amp;quot;Debug.logamp;quot;"/gt; lt;!--追加到文件--gt; lt;appendToFile value="true"/gt; lt;!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--gt; lt;rollingStyle value="Composite"/gt; lt;!--写到一个文件--gt; lt;staticLogFileName value="false"/gt; lt;!--单个文件大小。单位:KB|MB|GB--gt; lt;maximumFileSize value="200MB"/gt; lt;!--最多保留的文件数,设为"-1"则不限--gt; lt;maxSizeRollBackups value="-1"/gt; lt;!--日志格式--gt; lt;layout type="log4net.Layout.PatternLayout"gt; lt;conversionPattern value="%message"/gt; lt;/layoutgt; lt;filter type="log4net.Filter.LevelRangeFilter"gt; lt;param name="LevelMin" value="DEBUG" /gt; lt;param name="LevelMax" value="DEBUG" /gt; lt;/filtergt; lt;/appendergt; lt;/log4netgt; lt;startupgt; lt;supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /gt; lt;/startupgt;lt;/configurationgt;


1.2、创建网络工具类

此工具帮助类用于获取IP、浏览器信息等。代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Sockets;using System.Web;namespace MVCCuetomerExcepFilterDemo.Util{ /// lt;summarygt; /// 网络操作帮助类 /// lt;/summarygt; public class NetHelper { #region Ip(获取Ip) /// lt;summarygt; /// 获取Ip /// lt;/summarygt; public static string Ip { get { var result = string.Empty; if (HttpContext.Current != null) result = GetWebClientIp(); if (string.IsNullOrWhiteSpace(result)) result = GetLanIp(); return result; } } /// lt;summarygt; /// 获取Web客户端的Ip /// lt;/summarygt; private static string GetWebClientIp() { var ip = GetWebRemoteIp(); foreach (var hostAddress in Dns.GetHostAddresses(ip)) { if (hostAddress.AddressFamily == AddressFamily.InterNetwork) return hostAddress.ToString(); } return string.Empty; } /// lt;summarygt; /// 获取Web远程Ip /// lt;/summarygt; private static string GetWebRemoteIp() { return HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } /// lt;summarygt; /// 获取局域网IP /// lt;/summarygt; private static string GetLanIp() { foreach (var hostAddress in Dns.GetHostAddresses(Dns.GetHostName())) { if (hostAddress.AddressFamily == AddressFamily.InterNetwork) return hostAddress.ToString(); } return string.Empty; } #endregion #region Host(获取主机名) /// lt;summarygt; /// 获取主机名 /// lt;/summarygt; public static string Host { get { return HttpContext.Current == null Dns.GetHostName() : GetWebClientHostName(); } } /// lt;summarygt; /// 获取Web客户端主机名 /// lt;/summarygt; private static string GetWebClientHostName() { if (!HttpContext.Current.Request.IsLocal) return string.Empty; var ip = GetWebRemoteIp(); var result = Dns.GetHostEntry(IPAddress.Parse(ip)).HostName; if (result == "localhost.localdomain") result = Dns.GetHostName(); return result; } #endregion #region Browser(获取浏览器信息) /// lt;summarygt; /// 获取浏览器信息 /// lt;/summarygt; public static string Browser { get { if (HttpContext.Current == null) return string.Empty; var browser = HttpContext.Current.Request.Browser; return string.Format("{0} {1}", browser.Browser, browser.Version); } } #endregion }}


2、创建自定义异常类

正如上一篇文章中提到的,要创建自定义异常类,只需要创建一个从HandleErrorAttribute继承的类,并重写OnException方法。自定义异常类的代码如下:

using MVCCuetomerExcepFilterDemo.Models;using MVCCuetomerExcepFilterDemo.Util;using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace MVCCuetomerExcepFilterDemo.Extension{ /// lt;summarygt; /// 错误日志(Controller发生异常时会执行这里) /// lt;/summarygt; public class ExceptionFilters : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { WriteLog(filterContext); base.OnException(filterContext); filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.StatusCode = 200; } /// lt;summarygt; /// 写入日志(log4net) /// lt;/summarygt; /// lt;param name="context"gt;提供使用lt;/paramgt; private void WriteLog(ExceptionContext context) { if (context == null) return; var log = LogFactory.GetLogger(context.Controller.ToString()); Exception Error = context.Exception; LogMessageEntity logMessage = new LogMessageEntity(); logMessage.OperationTime = DateTime.Now; logMessage.Url = HttpContext.Current.Request.RawUrl; logMessage.Class = context.Controller.ToString(); logMessage.Ip = NetHelper.Ip; logMessage.Host = NetHelper.Host; logMessage.Browser = NetHelper.Browser; // 这里为了方便直接用默认的,真实案例中不能这样写 logMessage.UserName = "admin"; if (Error.InnerException == null) { logMessage.ExceptionInfo = Error.Message; } else { logMessage.ExceptionInfo = Error.InnerException.Message; } string strMessage = new LogFormat().ExceptionFormat(logMessage); log.Error(strMessage); } }}


3、创建控制器

控制器中有一个登录方法,代码如下:

using MVCCuetomerExcepFilterDemo.Extension;using MVCCuetomerExcepFilterDemo.Models;using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Security;namespace MVCCuetomerExcepFilterDemo.Controllers{ public class AccountController : Controller { // GET: Account public ActionResult Index() { return View(); } /// lt;summarygt; /// 登录成功显示的视图 /// lt;/summarygt; /// lt;returnsgt;lt;/returnsgt; public ActionResult Welcome() { return View(); } /// lt;summarygt; /// 显示登录视图 /// lt;/summarygt; /// lt;returnsgt;lt;/returnsgt; public ActionResult LogOn() { LogOnViewModel model = new LogOnViewModel(); return View(model); } /// lt;summarygt; /// 处理用户点击登录提交回发的表单 /// lt;/summarygt; /// lt;param name="model"gt;lt;/paramgt; /// lt;returnsgt;lt;/returnsgt; [HttpPost] [ExceptionFilters] public ActionResult LogOn(LogOnViewModel model) { try { string userName = model.UserName.Trim(); int password = Convert.ToInt32(model.Password); // 用户名是admin,密码是123456表示验证通过 if (userName.Equals("admin")amp;amp;password.Equals(123456)) { // 判断是否勾选了记住我 if (model.RememberMe) { //2880分钟有效期的cookie FormsAuthentication.SetAuthCookie(model.UserName, true); } else { //会话cookie FormsAuthentication.SetAuthCookie(model.UserName, false); } // 跳转到Account控制器的Welcome方法 return RedirectToAction("Welcome"); } else { return View(model); } } catch (Exception ex) { // 抛出异常 throw; } } }}


4、测试

在控制器代码中,如果输入的用户名是admin,密码是123456,就会通过,然后显示欢迎视图。如果密码转换失败,将记录异常日志。

首先输入正确的用户名和密码:


单击登录,然后显示欢迎视图:


这次输入错误的密码:


再次单击登录查看生成的日志:


在上面的代码中,我们在LogOn()方法上使用了ExceptionFilters特性,这样当控制器出现异常时,就会进入ExceptionFilters自定义异常类并记录日志。但是,有一个问题:如果你使用这种方法,你必须在每个动作方法中添加这个特性。如果动作方法很多,写起来很烦,有什么好办法吗?可以在控制器中添加ExceptionFilters特性,针对的是整个控制器中的动作。那么有没有更简单的方法呢?查看App_Start文件夹下的FilterConfig定义:

using MVCCuetomerExcepFilterDemo.Extension;using System.Web;using System.Web.Mvc;namespace MVCCuetomerExcepFilterDemo{ public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } }}

您可以看到这里添加了HandleErrorAttribute类。如果换成自定义异常类呢?修改后的FilterConfig文件如下:

using MVCCuetomerExcepFilterDemo.Extension;using System.Web;using System.Web.Mvc;namespace MVCCuetomerExcepFilterDemo{ public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //filters.Add(new HandleErrorAttribute()); // 使用自定义异常类 filters.Add(new ExceptionFilters()); } }}

AccountController代码修改如下:

using MVCCuetomerExcepFilterDemo.Extension;using MVCCuetomerExcepFilterDemo.Models;using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Security;namespace MVCCuetomerExcepFilterDemo.Controllers{ public class AccountController : Controller { // GET: Account public ActionResult Index() { return View(); } /// lt;summarygt; /// 登录成功显示的视图 /// lt;/summarygt; /// lt;returnsgt;lt;/returnsgt; public ActionResult Welcome() { return View(); } /// lt;summarygt; /// 显示登录视图 /// lt;/summarygt; /// lt;returnsgt;lt;/returnsgt; public ActionResult LogOn() { LogOnViewModel model = new LogOnViewModel(); return View(model); } /// lt;summarygt; /// 处理用户点击登录提交回发的表单 /// lt;/summarygt; /// lt;param name="model"gt;lt;/paramgt; /// lt;returnsgt;lt;/returnsgt; [HttpPost] // [ExceptionFilters] public ActionResult LogOn(LogOnViewModel model) { try { string userName = model.UserName.Trim(); int password = Convert.ToInt32(model.Password); // 用户名是admin,密码是123456表示验证通过 if (userName.Equals("admin")amp;amp;password.Equals(123456)) { // 判断是否勾选了记住我 if (model.RememberMe) { //2880分钟有效期的cookie FormsAuthentication.SetAuthCookie(model.UserName, true); } else { //会话cookie FormsAuthentication.SetAuthCookie(model.UserName, false); } // 跳转到Account控制器的Welcome方法 return RedirectToAction("Welcome"); } else { return View(model); } } catch (Exception ex) { // 抛出异常 throw; } } }}

这样,当异常发生时,它会自动进入自定义异常类,然后记录日志。

这就是这篇关于MVC自定义异常过滤器在ASP.NET的用例的文章。希望对大家的学习有所帮助>

0

精彩评论

暂无评论...
验证码 换一张
取 消