【C#】.net core2.1,自定义全局类对API接口和视图页面产生的异常统一处理

简介: 在开发一个网站项目时,异常处理和过滤功能是最基础的模块 本篇文章就来讲讲,如何自定义全局异常类来统一处理
作者:小5聊基础
简介:一只喜欢全栈方向的程序员,欢迎咨询,尽绵薄之力答疑解惑
编程原则:Write Less Do More
  • 流程图

image.png

【基本信息】

1)操作系统:windows11 <br/>
2)开发工具:VS 2017 <br/>
3)开发语言:C# <br/>
4)开发框架:.net core 2.1 <br/>
5)关键类:IAsyncExceptionFilter <br/>

【创建全局异常过滤类】

技术日新月异,同一个功能,版本肯定会在不停更新升级,除非已经弃用,因此,需要针对版本进行使用,否则可能会因为版本不用导致报错<br/>
1)继承接口类,IAsyncExceptionFilter <br/>
类来自的dll为,Microsoft.AspNetCore.Mvc.Abstractions.dll <br/>
版本:2.1.1 <br/>
2)实现接口方法,OnExceptionAsync <br/>
关键对象,ExceptionContext context,在实现方法类直接接收这个参数即可,这个参数会在目标方法发生异常后,赋值到这个参数里 <br/>

image.png

image.png

3)判断是否已经处理过异常 <br/>
如果有设置了多重嵌套过滤,那么可能会在第一层就已处理,或者根据业务需求进行灵活设定
context.ExceptionHandled==false; //未处理

4)请求协议 <br/>
可以根据http和https进行请求协议判断,也许在项目上需要对这两个请求协议做一个区别判断
context.HttpContext.Request.IsHttps

5)请求地址 <br/>
string url = http + context.HttpContext.Request.Host + context.HttpContext.Request.Path;

image.png

6)通过设置一个小技巧来判断,当前请求时api还是页面 <br/>
[Route("api/[controller]/[action]")] <br/>
bool isApi = url.IndexOf("/api/") > 0 ? true : false; <br/>
页面api标识来判断 <br/>

7)api和页面的post请求,响应json数据,页面get请求则返回页面信息

  • 类全部代码
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Text;
using System.Threading.Tasks;

namespace myweb.Class
{
    /// <summary>
    /// 异常处理 - 发生异常
    /// </summary>
    public class ExceptionFilter : IAsyncExceptionFilter
    {
        /// <summary>
        /// 重写OnExceptionAsync方法,定义自己的处理逻辑
        /// 测试方法-api:localhost:44345/api/LoginRegister/Test
        /// 测试方法-页面:localhost:44345/Home/Test
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task OnExceptionAsync(ExceptionContext context)
        {
            try
            {
                if (context.ExceptionHandled == false)
                {
                    //写入日志

                    //请求地址
                    string http = (context.HttpContext.Request.IsHttps ? "https://" : "http://");
                    string url = http + context.HttpContext.Request.Host + context.HttpContext.Request.Path;

                    bool isApi = url.IndexOf("/api/") > 0 ? true : false;
                    if (isApi)
                    {
                        var result = new 
                        {
                            message = context.Exception.Message.ToString(),
                            code = 198
                        };

                        context.Result = new ContentResult
                        {
                            StatusCode = StatusCodes.Status200OK,
                            ContentType = "application/json;charset=utf-8",
                            Content = JsonConvert.SerializeObject(result)
                        };
                    }
                    else
                    {
                        StringBuilder errorMessage = new StringBuilder();

                        //请求类型
                        var method = context.HttpContext.Request.Method;
                        int code = context.HttpContext.Response.StatusCode;
                        if (method.ToLower() == "Get".ToLower())
                        {
                            errorMessage.Clear();
                            errorMessage.Append($"<meta name=\"viewport\" content=\"width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\">");
                            errorMessage.Append($"<h1>请求页面发生异常</h1>");
                            errorMessage.Append($"<p>URL:{url}</p>");
                            errorMessage.Append($"<p>StatusCode:{code}</p>");
                            errorMessage.Append($"<p>GET</p>");

                            context.HttpContext.Response.ContentType = "text/html;charset=utf-8";
                            context.HttpContext.Response.StatusCode = 200;

                            using (var responseStream = context.HttpContext.Response.Body)
                            {
                                responseStream.Write(Encoding.Default.GetBytes(errorMessage.ToString()));
                            }
                        }
                        else
                        {
                            errorMessage.Clear();
                            errorMessage.Append($"请求页面发生异常,");
                            errorMessage.Append($"URL:{ url},");
                            errorMessage.Append($"StatusCode:{code},");
                            errorMessage.Append($"POST");

                            var result = new
                            {
                                message = errorMessage.ToString(),
                                code = 404
                            };

                            context.HttpContext.Response.ContentType = "application/json;charset=utf-8";
                            context.HttpContext.Response.StatusCode = 200;
                            using (var responseStream = context.HttpContext.Response.Body)
                            {
                                responseStream.Write(Encoding.Default.GetBytes(JsonConvert.SerializeObject(result)));
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                //写入到txt
            }


            context.ExceptionHandled = true; //设置为true,表示异常已经被处理了

            return Task.CompletedTask;
        }
    }
}

【Startup启动类设置】

1)在ConfigureServices方法下设置 <br/>
因为是针对MVC方法进行异常过滤处理,所以需要在AddMvc方法进行设置

  • 部分代码
public IServiceProvider ConfigureServices(IServiceCollection services)
//===添加MVC组件===
services.AddMvc(options=> {
    options.Filters.Add(typeof(ExceptionFilter)); //全局异常过滤
});
相关文章
|
26天前
|
设计模式 开发框架 安全
C# 一分钟浅谈:GraphQL API 与 C#
本文介绍了 GraphQL API 的基本概念及其优势,并通过 C# 实现了一个简单的 GraphQL 服务。GraphQL 是一种高效的 API 查询语言,允许客户端精确请求所需数据,减少不必要的数据传输。文章详细讲解了如何使用 `GraphQL.NET` 库在 C# 中创建和配置 GraphQL 服务,并提供了常见问题的解决方案和代码示例。
42 4
|
7天前
|
人工智能 自然语言处理 API
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
谷歌推出的Multimodal Live API是一个支持多模态交互、低延迟实时互动的AI接口,能够处理文本、音频和视频输入,提供自然流畅的对话体验,适用于多种应用场景。
48 3
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
|
3天前
|
前端开发 API 数据库
Next 编写接口api
Next 编写接口api
|
9天前
|
XML JSON 缓存
阿里巴巴商品详情数据接口(alibaba.item_get) 丨阿里巴巴 API 实时接口指南
阿里巴巴商品详情数据接口(alibaba.item_get)允许商家通过API获取商品的详细信息,包括标题、描述、价格、销量、评价等。主要参数为商品ID(num_iid),支持多种返回数据格式,如json、xml等,便于开发者根据需求选择。使用前需注册并获得App Key与App Secret,注意遵守使用规范。
|
8天前
|
JSON API 开发者
淘宝买家秀数据接口(taobao.item_review_show)丨淘宝 API 实时接口指南
淘宝买家秀数据接口(taobao.item_review_show)可获取买家上传的图片、视频、评论等“买家秀”内容,为潜在买家提供真实参考,帮助商家优化产品和营销策略。使用前需注册开发者账号,构建请求URL并发送GET请求,解析响应数据。调用时需遵守平台规定,保护用户隐私,确保内容真实性。
|
8天前
|
搜索推荐 数据挖掘 API
淘宝天猫商品评论数据接口丨淘宝 API 实时接口指南
淘宝天猫商品评论数据接口(Taobao.item_review)提供全面的评论信息,包括文字、图片、视频评论、评分、追评等,支持实时更新和高效筛选。用户可基于此接口进行数据分析,支持情感分析、用户画像构建等,同时确保数据使用的合规性和安全性。使用步骤包括注册开发者账号、创建应用获取 API 密钥、发送 API 请求并解析返回数据。适用于电商商家、市场分析人员和消费者。
|
18天前
|
JSON API 开发工具
淘宝实时 API 接口丨淘宝商品详情接口(Taobao.item_get)
淘宝商品详情接口(Taobao.item_get)允许开发者获取商品的详细信息,包括基本信息、描述、卖家资料、图片、属性及销售情况等。开发者需注册账号、创建应用并获取API密钥,通过构建请求获取JSON格式数据,注意遵守平台规则,合理使用接口,确保数据准确性和时效性。
|
19天前
|
JSON 安全 API
Python调用API接口的方法
Python调用API接口的方法
86 5
|
19天前
|
JSON 缓存 监控
淘宝商品详情接口(Taobao.item_get)丨淘宝API接口指南
淘宝商品详情接口(Taobao.item_get)允许开发者通过HTTP GET方法获取淘宝商品的详细信息,包括商品ID、价格、库存等。请求需包含key、secret、num_iid等必选参数,支持缓存及多种返回格式。此接口广泛应用于电商数据分析、商品选品、价格监控等领域,提升商家运营效率。
|
23天前
|
JSON 搜索推荐 API
LAZADA关键词搜索API接口的获取与应用
Lazada作为东南亚领先的电商平台,为满足开发者和商户需求,开放了关键词搜索API接口。本文详细介绍该接口的获取与应用,助力提升电商业务效率。接口支持关键词搜索、指定搜索范围和排序方式,提供精准、灵活且全面的数据支持,促进电商应用和服务的优化与创新。
24 3