首页 > 编程语言 >asp.net core之异常处理

asp.net core之异常处理

时间:2023-08-03 15:58:06浏览次数:33  
标签:core asp Response context Error Home net 异常 public

在开发过程中,处理错误是一个重要的方面。ASP.NET Core提供了多种方式来处理错误,以确保应用程序的稳定性和可靠性。

TryCatch

TryCatch是最常见也是最基础的一种异常处理方式,只需要用TryCatch把执行代码包起来,即可捕获异常。
格式如下:

try
{
    // 执行操作
    doAny();
}
catch (Exception ex)
{
    // 处理异常
    doExceptionHandling();
}

这属于最基本的异常处理方式,这里就不加上实操代码了。本文主要讲解asp.net core中的其他异常处理方式。

开发人员异常页

ASP.NET Core Web应用在以下情况下默认启用开发人员异常页,用于显示未经处理的请求异常的详细信息。
ASP.NET Core 应用在以下情况下默认启用开发人员异常页:

  • 在开发环境中运行。
  • 使用当前模板创建的应用,即使用 WebApplication.CreateBuilder。 使用 WebHost.CreateDefaultBuilder 创建的应用必须通过在 Configure 中调用 app.UseDeveloperExceptionPage 来启用开发人员异常页。

开发人员异常页运行在中间件管道的前面部分,以便它能够捕获随后中间件中抛出的未经处理的异常。
这里我们新建一个MVC项目,使用WebApplication.CreateBuilder,所以不需要显式调用app.UseDeveloperExceptionPage 来启用开发人员异常页,在HomeController中添加一个Thorw方法直接抛出异常:

using LearnException.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;

namespace LearnException.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }
        public IActionResult Throw()
        {
            throw new Exception("Customer Excetion");
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

启动项目,然后访问/Home/Throw路径。
image.png
可以看到这个页面可以看到我们的详细错误信息,包括异常栈,Query参数, Cookies参数,HTTP请求Headers信息以及路由信息。
这个页面在开发阶段,非常利于我们排查错误。

异常处理程序页

由于我们的一些异常信息不便在非开发环境展示,所以在非开发环境,我们需要一个异常处理程序页。
若要为生产环境配置自定义错误处理页,请调用 UseExceptionHandler。 此异常处理中间件:

  • 捕获并记录未经处理的异常。
  • 使用指示的路径在备用管道中重新执行请求。 如果响应已启动,则不会重新执行请求。 模板生成的代码使用 /Home/Error 路径重新执行请求。

在我们创建的MVC模板的Program中,有这样的代码:

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
}

表示在非开发环境中启用此异常处理中间件。这里的"/Home/Error"表示跳转到该路由。该路由为异常处理页面。
在模板Views/Shared下面我们可以看到一个Error.cshtml,和Models下面有一个ErrorViewModel,这就是默认的异常处理程序页。
在上面HomeController的代码中我们可以看到一个Error的Action,此Action指向Error页面。我们试试直接起启用app.UseExceptionHandler("/Home/Error"),放开在非开发环境才使用的条件:

//if (!app.Environment.IsDevelopment())
//{
    app.UseExceptionHandler("/Home/Error");
//}

分别请求/Home/Error和/Home/Throw路劲
image.png
image.png
可以看到/Home/Throw也是跳转到Error页面,但是没有详细的异常信息。

自定义异常处理程序页

除了上述的方式,我们在需要自定义异常处理程序页时,可以使用app.UseExceptionHandler的另一个重载方法:

app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;

            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;

            await context.Response.WriteAsync("An exception was thrown.");

            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();

            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync(" The file was not found.");
            }

            if (exceptionHandlerPathFeature?.Path == "/")
            {
                await context.Response.WriteAsync(" Page: Home.");
            }
        });
    });

在上面代码中exceptionHandlerApp是一个IApplicationBuilder,本质是添加一个终结点中间件去处理响应内容,上面内容包括了修改Http响应的StatusCode,ContentType,以及响应内容。
我们在HomeController中继续添加一个FileNotFound的Action。

public IActionResult FileNotFound()
{
	throw new FileNotFoundException();
}

启动项目,分别请求/Home/Throw和/Home/FileNotFound。
image.png
image.png
可以看到,响应内容和我们配置的一致。
由上面表现,其实我们可以想到,如何自定义一个异常处理中间件。

 public class MyExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public MyExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;

            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;

            await context.Response.WriteAsync("An exception was thrown.");


            if (ex is FileNotFoundException)
            {
                await context.Response.WriteAsync(" The file was not found.");
            }
        }
    }
}

在Program添加中间件

app.UseMiddleware<MyExceptionMiddleware>();

image.png
可以看到,效果完全一致。
除此之外,我们还有使用ExceptionFilter的方式去处理异常,只要实现实现 IExceptionFilter 或 IAsyncExceptionFilter即可。
添加一个MyExceptionFilter

public class MyExceptionFilter : IAsyncExceptionFilter
{
    public async Task OnExceptionAsync(ExceptionContext context)
    {
        context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;

        // using static System.Net.Mime.MediaTypeNames;
        context.HttpContext.Response.ContentType = Text.Plain;

        await context.HttpContext.Response.WriteAsync("An exception was thrown. by MyExceptionFilter");
    	context.ExceptionHandled = true;
    }
}

在HomeController添加一个Filter的Action。

[TypeFilter(typeof(MyExceptionFilter))]
public IActionResult Filter()
{
    throw new Exception("MyExceptionFilter Excetion");
}

启动项目,访问/Home/Filter路径。
image.png
可以看到效果跟预想的一致。

ASP.NET Core提供了多种方式来处理错误。开发人员可以根据具体的需求选择适合的错误处理方式,并进行相应的处理和响应。通过合理的错误处理,可以提高应用程序的稳定性和可靠性,提供更好的用户体验。

欢迎进群催更。

image.png

标签:core,asp,Response,context,Error,Home,net,异常,public
From: https://www.cnblogs.com/fanshaoO/p/17603536.html

相关文章

  • kubernetes-卷记录
    title:"Kubernetes卷"date:2023-07-27T11:58:09+08:00categories:-category-subcategorycephfs允许将现有的fs挂载到pod中。在pod被删除时被保留,只是被卷卸载。configMap提供了向pod注入配置数据的方法。configMap对象可以被挂载为卷。apiVersion:v1kind:Podme......
  • Kubernetes 网络经过全过程思考输出
    title:"Kubernetes网络经过全过程思考输出"date:2023-07-26T10:31:23+08:00categories:-kubernetes-subcategorykubernetes网络从client到服务端经过全过程思考输出kubernetes网络流量的经历思考输出flowchartTB客户端GET请求-->到达Traefik-->Ingress已经......
  • AddMvcCore,AddControllers,AddControllersWithViews,AddRazorPages的区别
    AddMvc/AddMvcCore/AddControllers等区别1.services.AddMvcCore()只注册运行 Controller/RazorPages 必要的核心服务,确保 Pipeline 程序可动作,其馀如像 DataAnnotationModelValidation、身分验证等服务要自己加挂,除有特殊客制需求,一般不太常用。2.services.AddControl......
  • Win11 开启 telnet
    'telnet’不是内部或外部命令,也不是可运行的程序或批处理文件。首先我们打开底部“开始菜单”,如图所示、接着打开其中的“设置”。然后进入左边的“应用”设置。再打开右上角“可选功能”打开后,下拉到最底部,打开“更多windows功能”随后找到“telnet客户端”,勾选开启后点......
  • 关闭防火墙,主机与虚拟机VMnet8在同一网段,主机无法ping通虚拟机问题解决
    因需要进行oss数据迁移至eos,需要liunx环境,于是在本机上使用虚拟机安装了centos7,安装后ifconfig查看虚拟机ip,网络模式是NAT然后ping主机以及百度网,均可ping通,说明虚拟机网络正常  但是使用xshell后,一直无法连接,主机ping虚拟机,请求超时,以为是虚拟机防火墙问题,关闭虚拟机防火......
  • [回馈]ASP.NET Core MVC开发实战之商城系统(五)
    经过一段时间的准备,新的一期【ASP.NETCoreMVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习......
  • 【HMS Core】【Push Kit】每天只能收到两条推送、状态码80100018
    【问题描述1】每天只能收到2条推送消息,其余的都无法收到【解决方案】1、请是否开通了消息自分类,因为现在是有咨询营销类消息限制的。没有使用自分类权益的话默认是资讯营销类消息。https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-restriction-d......
  • 【HMS Core】位置服务逆地理编码请求错误问题
    【关键字】HMS、位置服务、逆地理编码【问题描述】有开发者反馈在集成位置服务-逆地理编码时,出现了请求报错的问题。后端请求逆地理编码错误{   "returnCode":"010010",   "returnDesc":"INVALID_REQUEST"}【问题分析】1、一开始认为是cp的请求参数有误,缺少了必选的参数。......
  • 记一次 .NET某培训学校系统 内存碎片化分析
    一:背景1.讲故事前些天有位朋友微信上找到我,说他们学校的Web系统内存一直下不去,让我看下到底是怎么回事,老规矩让朋友生成一个dump文件丢给我,看一下便知。二:WinDbg分析1.托管还是非托管要想看托管还是非托管,可以用!address-summary观察下内存段。0:000>!address-summ......
  • asp.net中获得客户端的IP地址
    原文链接:https://blog.csdn.net/as2712101/article/details/9357777今天看到的一个方法,来查下: 通常我们都通过下面的代码获得IP:   string ip=System.Web.HttpContext.Current.Request.UserHostAddress;    或 string ip=System.Web.HttpContext.Current.Request.S......