【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)); //全局异常过滤
});
相关文章
|
7天前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
37 11
|
12天前
|
存储 缓存 监控
如何高效爬取天猫商品数据?官方API与非官方接口全解析
本文介绍两种天猫商品数据爬取方案:官方API和非官方接口。官方API合法合规,适合企业长期使用,需申请企业资质;非官方接口适合快速验证需求,但需应对反爬机制。详细内容涵盖开发步骤、Python实现示例、反爬策略、数据解析与存储、注意事项及扩展应用场景。推荐工具链包括Playwright、aiohttp、lxml等。如需进一步帮助,请联系作者。
|
13天前
|
机器学习/深度学习 JSON 算法
淘宝拍立淘按图搜索API接口系列的应用与数据解析
淘宝拍立淘按图搜索API接口是阿里巴巴旗下淘宝平台提供的一项基于图像识别技术的创新服务。以下是对该接口系列的应用与数据解析的详细分析
|
25天前
|
JSON API 数据格式
淘宝商品评论数据API接口详解及JSON示例返回
淘宝商品评论数据API接口是淘宝开放平台提供的一项服务,旨在帮助开发者通过编程方式获取淘宝商品的评论数据。这些数据包括评论内容、评论时间、评论者信息、评分等,对于电商分析、用户行为研究、竞品分析等领域都具有极高的价值。
|
1月前
|
JSON API 数据格式
阿里巴巴商品详情接口(阿里巴巴 API 系列)
在电商开发中,获取阿里巴巴商品详情信息对数据分析、竞品研究等至关重要。通过调用其商品详情接口,开发者可获取标题、价格、图片、描述等数据,满足多种业务需求。接口采用HTTPS协议,支持GET/POST请求,返回JSON格式数据。示例代码展示了如何使用Python的requests库进行接口请求,需传递商品ID和访问令牌。实际应用时,请依据官方文档调整参数并确保安全性。
62 10
|
1月前
|
JSON API 数据格式
eBay商品详情接口(ebay API系列)
eBay 商品详情接口是电商从业者、开发者和数据分析师获取商品详细信息的重要工具,涵盖标题、价格、库存、卖家信息等。使用前需在 eBay 开发者平台注册并获取 API 凭证,通过 HTTP GET 请求调用接口,返回 JSON 格式数据。Python 示例代码展示了如何发送请求并解析响应,确保合法合规使用数据。
61 12
|
1月前
|
监控 供应链 搜索推荐
亚马逊商品详情接口(亚马逊 API 系列)
亚马逊作为全球最大的电商平台之一,提供了丰富的商品资源。开发者和电商从业者可通过亚马逊商品详情接口获取商品的描述、价格、评论、排名等数据,对市场分析、竞品研究、价格监控及业务优化具有重要价值。接口基于MWS服务,支持HTTP/HTTPS协议,需注册并获得API权限。Python示例展示了如何使用mws库调用接口获取商品详情。应用场景包括价格监控、市场调研、智能选品、用户推荐和库存管理等,助力电商运营和决策。
102 23
|
1月前
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
66 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
1月前
|
JSON 数据挖掘 API
lazada商品详情接口 (lazada API系列)
Lazada 是东南亚知名电商平台,提供海量商品资源。通过其商品详情接口,开发者和商家可获取商品标题、价格、库存、描述、图片、用户评价等详细信息,助力市场竞争分析、商品优化及库存管理。接口采用 HTTP GET 请求,返回 JSON 格式的响应数据,支持 Python 等语言调用。应用场景包括竞品分析、价格趋势研究、用户评价分析及电商应用开发,为企业决策和用户体验提升提供有力支持。
91 21
|
1月前
|
数据采集 JSON 监控
速卖通商品列表接口(以 AliExpress Affiliate 商品查询 API 为例)
以下是使用 Python 调用速卖通商品列表接口(以 AliExpress Affiliate 商品查询 API 为例)的代码示例。该示例包含准备基础参数、生成签名、发送请求和处理响应等关键步骤,并附有详细注释说明。代码展示了如何通过公共参数和业务参数构建请求,使用 HMAC-SHA256 加密生成签名,确保请求的安全性。最后,解析 JSON 响应并输出商品信息。此接口适用于商品监控、数据采集与分析及商品推荐等场景。注意需通过 OAuth2.0 获取 `access_token`,并根据官方文档调整参数和频率限制。