C#程序全局异常处理—WPF和Web API两种模式
C#程序的全局异常处理,网上搜下资料都是一大堆,我这里最近也是独立做一个B/S结构的小项目, 后面又增加了需求用WPF实现相同的功能,这里将我所使用的全局异常处理方式做一个简短的总结分享。
Web API项目的全局异常处理
这种项目下,我们可以直接自定义一个全局异常的过滤器,用来处理全局异常。具体步骤就是在WEB API项目中,定义一个继承自AppExceptionFilterAttribute的类,这个类需要引入命名空间Microsoft.AspNetCore.Mvc.Core.dll,一般来说如果是WEB API或者说MVC的项目,这个会自动帮我们引入或者说VS智能提示帮助我们引入。我们自定义的类只需要重写OnException方法即可,当然现在都推荐使用其异步模式OnExceptionAsync方法,我这里自定义的异常处理类是AppExceptionFilterAttribute,具体代码如下。
自定义的全局异常处理类AppExceptionFilterAttribute
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApi
{
[AttributeUsage(AttributeTargets.Method|AttributeTargets.Class,AllowMultiple =false,Inherited =false)]
public class AppExceptionFilterAttribute:ExceptionFilterAttribute
{
//private static ILog log = LogManager.GetLogger(typeof(AppExceptionFilter));//typeof放当前类
public override void OnException(ExceptionContext actionExecutedContext)
{
ActionDescriptor actionDescriptor = actionExecutedContext.ActionDescriptor;
if (actionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(SkipFilterAttribute)))
{
//判断如果操作方法有SkipFilterAttribute特性,则跳过自定义的过滤器的执行
base.OnException(actionExecutedContext);
return;
}
Exception ex = actionExecutedContext.Exception;
if (ex != null)
{
string ControllerName = actionDescriptor.RouteValues["controller"];
string ActionName = actionDescriptor.RouteValues["action"];
//log.Error(string.Format("Filter捕获到未处理异常:ControllerName={0},ActionName={1}, ExType={2},Source={3},Message={4},Exception={5}", ControllerName, ActionName, ex.GetType(), ex.Source, ex.Message, ex.ToString()));
JsonResult jsonResult = new JsonResult($"全局Filter已进行错误处理。{ex.Message}");
jsonResult.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
actionExecutedContext.Result = jsonResult;
}
actionExecutedContext.ExceptionHandled = true;
}
}
}
在上述代码中,只需要将AppExceptionFilterAttribute标记在方法的头上或者Controller的头上即可,如果在方法头上,当程序执行到此方法出现未处理异常时,会由AppExceptionFilterAttribute来处理。我们可以在AppExceptionFilterAttribute中集成日志组件,将错误的异常日记记录下来。如果在Controller的头上标记此特性,那么针对此Controller中定义的方法,在出现异常时都会进入到AppExceptionFilterAttribute来处理。如果想让某个方法不去使用此异常过滤器来处理。我们还可以加上一个跳过的处理操作,上面的代码中SkipFilterAttribute类就是用来做跳过自定义异常处理的功能,只需要定义个空的特性处理类即可,代码如下:
跳过自定义异常处理的特性类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApi
{
/// <summary>
/// 跳过过滤器的操作,定义在方法头上,带有此标记的方法不会去处理过滤
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class SkipFilterAttribute : Attribute
{
}
}
最后贴上一段在Controller中使用的代码示例,这个示例中我是在Controller的头上使用了特性类AppExceptionFilterAttribute,而在接口方法Get3DModelData的头上使用了SkipFilterAttribute特性做标记,因此Get3DModelData出现异常后进入AppExceptionFilterAttribute中检测到方法头上标记了SkipFilterAttribute,会跳过自定义异常处理。
Controller中使用自定义异常处理
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApi.Controllers
{
[AppExceptionFilter]
[Route("[controller]/[action]")]
[ApiController]
public class Dicom3DController : Controller
{
[SkipFilterAttribute]
[HttpPost]
public IActionResult Get3DModelData([FromBody]Dicom3DRequest request)
{
Dicom3DServer server = new Dicom3DServer();
D3Model model= server.Get3DData(request.StudyId, request.SeireisId,request.CurrentBatch);
return Json(model);
}
public IActionResult GetUserInfo()
{
return Json("success");
}
}
}
WPF全局异常处理
WPF程序的全局异常处理就更简单了,我们创建的WPF的项目入口类都是继承自System.Windows.Application类,默认创建的项目的入口类名为APP,我们在这个类中定义一个构造函数,在其中绑定三个异常事件即可,具体为什么需要三个,直接可以看我代码的注释即可。
WPF的全局异常处理
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
//当应用程序引发但未处理异常时出现,UI线程的异常,无法捕获多线程异常
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
//当某个异常未被捕获时出现,Thread多线程和UI线程都可以捕获
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
//未被观察到的Task多线程异常
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
}
private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true; //使用e.Handled能防止程序崩溃
MessageBox.Show($"Current_DispatcherUnhandledException:" + e.Exception.Message);
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show($"CurrentDomain_UnhandledException:" + (e.ExceptionObject as Exception).Message);
}
private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
MessageBox.Show($"TaskScheduler_UnobservedTaskException:" + e.Exception.Message);
}
}
}
C#程序全局异常处理—WPF和Web API两种模式的更多相关文章
- 开发H5程序或者小程序的时候,后端Web API项目在IISExpress调试中使用IP地址,便于开发调试
在我们开发开发H5程序或者小程序的时候,有时候需要基于内置浏览器或者微信开发者工具进行测试,这个时候可以采用默认的localhost进行访问后端接口,一般来说没什么问题,如果我们需要通过USB基座方式 ...
- 在Java Web程序中使用监听器可以通过以下两种方法
之前学习了很多涉及servlet的内容,本小结我们说一下监听器,说起监听器,编过桌面程序和手机App的都不陌生,常见的套路都是拖一个控件,然后给它绑定一个监听器,即可以对该对象的事件进行监听以便发生响 ...
- WPF程序将DLL嵌入到EXE的两种方法
WPF程序将DLL嵌入到EXE的两种方法 这一篇可以看作是<Visual Studio 版本转换工具WPF版开源了>的续,关于<Visual Studio 版本转换工具WPF版开源了 ...
- Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用
Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...
- WPF多线程UI更新——两种方法
WPF多线程UI更新——两种方法 前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对 ...
- win10应用程序添加到开机启动项的两种解决办法
原文 win10应用程序添加到开机启动项的两种解决办法 在windows10系统中,如果想让应用程序在开机之后自动运行起来,可以怎么做呢? 方法一: 1.首先创建应用程序的快捷方式 找到自己想加入开机 ...
- Elasticsearch模糊查询、多字段in查询、时间范围查询,DSL和java API两种方式
Elasticsearch模糊查询.多字段in查询.时间范围查询,DSL和java API两种方式 项目场景: Elasticsearch模糊查询某字段.多字段in查询.时间范围查询,通过DSL和ja ...
- [水煮 ASP.NET Web API2 方法论](1-1)在MVC 应用程序中添加 ASP.NET Web API
问题 怎么样将 Asp.Net Web Api 加入到现有的 Asp.Net MVC 项目中 解决方案 在 Visual Studio 2012 中就已经把 Asp.Net Web Api 自动地整合 ...
- [水煮 ASP.NET Web API2 方法论](1-2)在 WebForm 应用程序中添加 ASP.NET Web API
问题 怎么样将 Asp.Net Web Api 加入到 Asp.Net Web From 应用程序中 解决方案 在 Visual Studio 2013 中,创建新的 Web From,可以直接在&q ...
- [图形]图形API的两种模式
图形API可以分为retained-mode APIs(保存模式API)和immediate-mode APIs(中间模式API). Direct2D是immediate-mode API,而Wind ...
随机推荐
- adb基础指令
1.查看连接的设备 adb.exe devices/adb devices device表示连接成功,offline表示设备未连接或未响应 2.进入命令模式,指定哪台设备 adb -s 序列号 ...
- 如何减缓vm中慢插入的次数
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 偶然发现vm-storage的监控里有这样一个指标:vm_ ...
- ClickHouse(14)ClickHouse合并树MergeTree家族表引擎之VersionedCollapsingMergeTree详细解析
目录 建表语法 使用场景 合并算法 使用例子. 资料分享 参考文章 VersionedCollapsingMergeTree引擎继承自MergeTree并将折叠行的逻辑添加到合并数据部分的算法中.Ve ...
- 大数据面试题集锦-Hadoop面试题(二)-HDFS
你准备好面试了吗?这里有一些面试中可能会问到的问题以及相对应的答案.如果你需要更多的面试经验和面试题,关注一下"张飞的猪大数据分享"吧,公众号会不定时的分享相关的知识和资料. 目录 ...
- .net fromwork连接rabbitmq发布消息
1.创建连接工厂类 var factory = new RabbitMQ.Client.ConnectionFactory() { HostName = "120.237.72.46&quo ...
- 小白学k8s(6)使用kubespray部署k8s
kubespray部署k8s 准备 需要关闭防火墙 配置hosts 处理镜像 配置文件 运行 通过对应的镜像 运行代码 查看结果 出现的问题 墙 错误的配置 kubespray部署k8s 准备 kub ...
- go中bytes.Buffer使用小结
buffer 前言 例子 了解下bytes.buffer 如何创建bytes.buffer bytes.buffer的数据写入 写入string 写入[]byte 写入byte 写入rune 从文件写 ...
- 【2】Pycharm插件推荐,超级实用!每个小trick都可以快速提升变成效率!
相关文章: [1]Pycharm 主题设置推荐Material Theme UI以及编辑环境配置(字体大小和颜色) [2]Pycharm插件推荐,超级实用!每个小trick都可以快速提升变成效率! [ ...
- 8.2 C++ 引用与取别名
C/C++语言是一种通用的编程语言,具有高效.灵活和可移植等特点.C语言主要用于系统编程,如操作系统.编译器.数据库等:C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统.图形用户界面 ...
- 5、后端学习规划:.Net学习 - 学习规划系列文章
.Net是微软发布的一整套的软件编程解决方案.笔者从大学的时代开始就阅读.netframework的书籍了,但是当时没有进行实践.毕业后,笔者去了微软技术中心的公司上班,所以就接触了.net以及C#编 ...