ASP.NET mvc异常处理的方法

ASP.NET mvc异常处理的方法

第一种:全局异常处理

1.首先常见保存异常的类(就是将异常信息写入到文件中去)

public class LogManager

   {
       private string logFilePath = string.Empty;
       public LogManager(string logFilePath)
       {
           this.logFilePath = logFilePath;
           FileInfo file = new FileInfo(logFilePath);
           if (!file.Exists)
           {
               file.Create().Close();
           }
       }

       public void SaveLog(string message, DateTime writerTime)
       {
           string log = writerTime.ToString() + ":" + message;
           StreamWriter sw = new StreamWriter(logFilePath, true);
           sw.WriteLine(log);
           sw.Close();
       }
   }

2.编写一个异常的基类让其继承自controller类

public class BaseExceptionController : Controller
   {
       protected override void OnException(ExceptionContext filterContext)
       {
           LogManager logManager = new LogManager(Server.MapPath("~/Exception.txt"));
           logManager.SaveLog(filterContext.Exception.Message, DateTime.Now);
           base.OnException(filterContext);
       }
   }        

3.编写控制器,让其继承自上面的异常基类

public class ExceptionController : BaseExceptionController
   {
       public ActionResult Index()
       {
           throw new Exception("我抛出异常了!");//这个是为了查看结果故意抛出的异常
       }
   }

通过上面的方式可以对整个控制器中的action都能进行异常的获取,但是这种方式不太灵活,那么就看第二种方式

第二种:控制器异常处理

这种方式就在需要进行异常处理的controller中重写OnException()方法即可,因为它本身继承了IExceptionFilter接口

public class ExceptionController : Controller
   {
       public ActionResult Index()
       {
           throw new Exception("我抛出异常了!");
       }

       protected override void OnException(ExceptionContext filterContext)
       {
           string filePath = Server.MapPath("~/Exception。txt");
           StreamWriter sw = System.IO.File.AppendText(filePath);
           sw.WriteLine(DateTime.Now.ToString() + ":" + filterContext.Exception.Message);
           sw.Close();
           base.OnException(filterContext);
           Redirect("/");
       }
   }    

前面两种都是在controller中重写OnException方法,这样只要controller中又异常,那么就会被捕捉并被处理,但是如果我们要针对某个action使用异常处理呢?那么我们就要用到下面的过滤器异常处理来进行。

第三种:过滤器异常处理

namespace MyMVC.Controllers
{
   public class ExceptionController : Controller
   {
       [Error]
       public ActionResult Index()
       {
           throw new Exception("过滤器异常!");
       }
   }
}

public class ErrorAttribute : HandleErrorAttribute
{
   public override void OnException(ExceptionContext filterContext)
   {
       base.OnException(filterContext);
       string path = filterContext.HttpContext.Server.MapPath("~/Exception.txt");
       StreamWriter sw = System.IO.File.AppendText(path);       sw.WriteLine(DateTime.Now.ToString()+":"+filterContext.Exception.Message);
       sw.Close();
   }
}        

第四种:路由异常处理

//设置路由参数
routes.MapRoute("ErrorHandling", "{*str}", new { controller = "Exception", action = "Missing" });
//一定要放在所有配置的最下面、
public ActionResult Missing(string str)
       {
           ViewData["ErrMsg"] = "您访问的页面出错了,"+str+" 时间:"+DateTime.Now.ToString();
           return View();
       }

第五种:动作异常处理

//首先设置:
 <system.web>
   <customErrors mode="On">
     <error statusCode="404" redirect="/Exception/Missing"/>
   </customErrors>
 </system.web>
       public ActionResult Missing(string str)
       {
           ViewData["ErrMsg"] = "您访问的页面出错了,"+str+" 时间:"+DateTime.Now.ToString();
           return View();
       }

授权处理(获取客户端信息)

public class SystemIAuthorizationFilter : IAuthorizationFilter
    {
        void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext)
        {
            //当前操作计算机用户 
            string pcName = ((System.Web.HttpServerUtilityWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Server).MachineName;
            //视图
            string action = ((System.Web.Mvc.ReflectedActionDescriptor)filterContext.ActionDescriptor).ActionName;
            //控制器
            string controller = ((System.Web.Mvc.ReflectedActionDescriptor)filterContext.ActionDescriptor).ControllerDescriptor.ControllerName;
            //请求时间
            string time = filterContext.RequestContext.HttpContext.Timestamp.ToString();
            //请求相对路径
            string absturl = ((System.Web.UnvalidatedRequestValuesWrapper)((System.Web.HttpRequestWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Request).Unvalidated).Url.AbsoluteUri;
            //状态
            string code = ((System.Web.HttpResponseWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Response).Status;
            // 浏览器版本
            string browser = ((System.Web.HttpBrowserCapabilitiesWrapper)((System.Web.HttpRequestWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Request).Browser).Type;
            //请求方式
            string gepPost = ((System.Web.HttpRequestWrapper)((System.Web.Mvc.Controller)filterContext.Controller).Request).RequestType;
            //本地主机名称解析DNS本身处理。
            string server = ((System.Web.HttpRequestWrapper)((System.Web.HttpContextWrapper)filterContext.HttpContext).Request).UserHostAddress;
            #region  server 说明
            /*
              * 版权(c)1993 - 2009微软(msft . o:行情)。
              *
              * 这是一个示例所使用的主机文件微软为Windows TCP / IP。
              *
              * 这个文件包含IP地址到主机名的映射。
                          每一个
              * 条目应该保存在单个行。
              IP地址应
              *被放置在第一列对应的主机名。
              *的IP地址和主机名应该由至少一个
              *空间。
              *
              *此外,评论(这样的)可能是插入的个人
              *线或后机器名称用“*”符号。
              *
              例如:
              *
              * 102.54.94.97 rhino.acme.com源服务器
              * 38.25.63.10 x.acme.com x客户机主机
              *本地主机名称解析DNS本身处理。
              * 127.0.0.1 localhost
              *::1 localhost
              */
            #endregion
            //用户
            //部门
            //职位
 
        }
    }

https://blog.csdn.net/zy0421911/article/details/54911712 MVC 自定义过滤器(Filter)实现路由控制、异常处理、授权处理(获取客户端信息)