ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

ASP.NET Core 中间件 自定义全局异常中间件以及 MVC异常过滤器作用

2021-12-19 01:32:14  阅读:168  来源: 互联网

标签:info 请求 自定义 app 中间件 管道 异常


原文:ASP.NET Core 中间件 自定义全局异常中间件以及 MVC异常过滤器作用

 

阅读目录

中间件是一种装配到应用管道以处理请求和响应的软件。 每个组件:

  • 选择是否将请求传递到管道中的下一个组件。
  • 可在管道中的下一个组件前后执行工作。

请求委托用于生成请求管道。 请求委托处理每个 HTTP 请求。

使用 RunMap 和 Use 扩展方法来配置请求委托。 可将一个单独的请求委托并行指定为匿名方法(称为并行中间件),或在可重用的类中对其进行定义。 这些可重用的类和并行匿名方法即为中间件,也叫中间件组件。 请求管道中的每个中间件组件负责调用管道中的下一个组件,或使管道短路。 当中间件短路时,它被称为“终端中间件”,因为它阻止中间件进一步处理请求。

将 HTTP 处理程序和模块迁移到 ASP.NET Core 中间件介绍了 ASP.NET Core 和 ASP.NET 4.x 中请求管道之间的差异,并提供了更多的中间件示例。

回到顶部

中间件顺序

 

 

 

 

 

 向 Startup.Configure 方法添加中间件组件的顺序定义了针对请求调用这些组件的顺序,以及响应的相反顺序。 此顺序对于安全性、性能和功能至关重要。

复制代码
 // 运行时调用此方法。使用此方法配置HTTP请求管道。
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // 启用swagger中间件
            app.UseSwaggerMiddleware();

            // 全局异常捕获
            app.UseErrorHandlingMiddleware();

            //静态文件
            app.UseUploadConfig();

            // 路由中间件
            app.UseRouting();

            // 跨域检查
            app.UseCors(_allowSpecificOrigins);

            // 启用多租户中间件(自定义)
            app.UseMultiTenant();

            // (认证中间件)启用Authentication中间件,遍历策略中的身份验证方案获取多张证件,最后合并放入HttpContext.User中
            app.UseAuthentication();

            // (授权中间件)对请求进行权限验证
            app.UseAuthorization();

           

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                //endpoints.MapControllerRoute("default", "{__tenant__=tenant1}/api/{controller=Home}/{action=Index}/{id?}");
                //endpoints.MapControllerRoute("default", "{__tenant__=}/api/{controller=Home}/{action=Index}");
            });
        }
复制代码

在上述代码中:

  • 在使用单个用户帐户创建新的 Web 应用时未添加的中间件已被注释掉。
  • 并非所有中间件都需要准确按照此顺序运行,但许多中间件必须遵循这个顺序。 例如:
    • UseCorsUseAuthentication 和 UseAuthorization 必须按照上述顺序运行。
    • 由于此错误UseCors 当前必须在 UseResponseCaching 之前运行。

以下 Startup.Configure 方法将为常见应用方案添加中间件组件:

  1. 异常/错误处理
    • 当应用在开发环境中运行时:
      • 开发人员异常页中间件 (UseDeveloperExceptionPage) 报告应用运行时错误。
      • 数据库错误页中间件报告数据库运行时错误。
    • 当应用在生产环境中运行时:
      • 异常处理程序中间件 (UseExceptionHandler) 捕获以下中间件中引发的异常。
      • HTTP 严格传输安全协议 (HSTS) 中间件 (UseHsts) 添加 Strict-Transport-Security 标头。
  2. HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
  3. 静态文件中间件 (UseStaticFiles) 返回静态文件,并简化进一步请求处理。
  4. Cookie 策略中间件 (UseCookiePolicy) 使应用符合欧盟一般数据保护条例 (GDPR) 规定。
  5. 用于路由请求的路由中间件 (UseRouting)。
  6. 身份验证中间件 (UseAuthentication) 尝试对用户进行身份验证,然后才会允许用户访问安全资源。
  7. 用于授权用户访问安全资源的授权中间件 (UseAuthorization)。
  8. 会话中间件 (UseSession) 建立和维护会话状态。 如果应用使用会话状态,请在 Cookie 策略中间件之后和 MVC 中间件之前调用会话中间件。
  9. 用于将 Razor Pages 终结点添加到请求管道的终结点路由中间件(带有 MapRazorPages 的 UseEndpoints)。
回到顶部

内置中间件

ASP.NET Core 附带以下中间件组件。 “顺序”列提供备注,以说明中间件在请求处理管道中的放置,以及中间件可能会终止请求处理的条件。 如果中间件让请求处理管道短路,并阻止下游中间件进一步处理请求,它被称为“终端中间件”。 若要详细了解短路,请参阅使用 IApplicationBuilder 创建中间件管道部分。

 

 

 自定义中间件  比如异常中间件

首先,创建一个中间件ExceptionMiddleware

复制代码
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace NetLock.Presentation.Api.Middleware
{
    public class ErrorHandlingMiddleware
    {
        private readonly RequestDelegate next;

        private readonly ILogger<ErrorHandlingMiddleware> _logger;
        public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger)
        {
            this.next = next;
            this._logger = logger;
        }
        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context, ex);
            }

        }


        private Task HandleExceptionAsync(HttpContext context, Exception ex)
        {
            //var code = HttpStatusCode.InternalServerError; // 500 if unexpected
            var code = StatusCodes.Status500InternalServerError;
            string info = "服务器内部错误,无法完成请求";
            if (ex is Exception)
            {
                code = 401;
                info = ex.Message == "" ? "未登录" : ex.Message;

            }
            else if (ex is UnAuthorizeException)
            {
                code = 401;
                info = ex.Message == "" ? "无权访问" : ex.Message;
            }
            else
            {
                switch (context.Response.StatusCode)
                {
                    case 401:
                        info = "没有权限";
                        break;
                    case 404:
                        info = "未找到服务";
                        break;
                    case 403:
                        info = "服务器理解请求客户端的请求,但是拒绝执行此请求";
                        break;
                    case 500:
                        info = "服务器内部错误,无法完成请求";
                        break;
                    case 502:
                        info = "请求错误";
                        break;
                    default:
                        info = ex.Message;
                        break;
                }

            }


            _logger.LogError(info); // todo:可记录日志,如通过注入Nlog等三方日志组件记录

            var result = JsonConvert.SerializeObject(new { Coede= code.ToString(), Message = info });
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = code;
            return context.Response.WriteAsync(result);
        }
    }
}
复制代码

管道的添加顺序决定了它的执行顺序,所以如果您想扩大异常捕获的范围,可以将该管道放置在 Configure 的第一行。 但是!! 您会发现,这个默认的AspNet Core项目不是已经在第一行弄了一个异常处理么?

复制代码
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
}
复制代码

这行代码大家在初始化新AspNetCore项目时就会看到,也有可能您只有上半段,这和模板有关系。不过这都没有关系,它的作用就是捕获和处理异常而已。关于 UseDeveloperExceptionPage 该扩展咱们就不多说了,它的意思是:对于开发模式,一旦报错就会跳转到错误堆栈页面。 而第二个 UseExceptionHandler 就很有意思了,从它命名就可以看出,它肯定是个错误拦截程序。那么它和咱们自定义的异常处理管道有什么区别呢?

“不指定肯定有个默认吧!” 是的,它就是默认的错误处理。所以,它其实也是一个中间件,它的真身叫做 ExceptionHandlerMiddleware。在使用 UseExceptionHandler 方法时,我们可以选填各种参数。比如上方的代码,填入了 "/Error" 参数,表示当产生异常的时候,将定向到对应路径,此处就定位的是: “http://localhost:5001/Error” 。当然您也可以随意指定页面,比如 漂亮的乔殿下页面。

标签:info,请求,自定义,app,中间件,管道,异常
来源: https://www.cnblogs.com/Insist-Y/p/15706548.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有