代码之家  ›  专栏  ›  技术社区  ›  chris31389

如何在.NET Core中捕获异常并用状态代码响应

  •  4
  • chris31389  · 技术社区  · 6 年前

    我正在运行一个.Net核心Web API项目。 我有一个启动文件(如下)。在 Startup.ConfigureServices(...) 方法,我添加了一个创建IFoo实例的工厂方法。我想捕捉IFooFactory抛出的任何异常,并返回一个更好的带有状态代码的错误消息。目前我收到一个500错误的异常消息。有人能帮忙吗?

    500 Error Message

    public interface IFooFactory
    {
        IFoo Create();  
    }
    
    public class FooFactory : IFooFactory
    {
        IFoo Create()
        {
            throw new Exception("Catch Me!");
        }
    }
    
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IFooFactory,FooFactory>();
            services.AddScoped(serviceProvider => {
                IFooFactory fooFactory = serviceProvider.GetService<IFooFactory>();
                return fooFactory.Create(); // <== Throws Exception
            });
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   ste-fu    6 年前

    因此,当我以两种不同的方式阅读问题时,我发布了两个不同的答案-大量删除/取消删除/编辑-不确定哪一个真正回答了您的问题:

    若要找出应用程序启动时出现的问题以及根本不起作用,请尝试以下操作:

    在中使用开发人员异常页 Startup :

    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
                               ILoggerFactory loggerFactory)
    {
        app.UseDeveloperExceptionPage();
    }
    

    Program 班级:

    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .CaptureStartupErrors(true) // useful for debugging
            .UseSetting("detailedErrors", "true") // what it says on the tin
            .Build();
    
        host.Run();
    }
    

    如果希望在api正常工作时处理偶尔出现的异常,则可以使用一些中间件:

    public class ExceptionsMiddleware
    {
        private readonly RequestDelegate _next;
    
        /// <summary>
        /// Handles exceptions
        /// </summary>
        /// <param name="next">The next piece of middleware after this one</param>
        public ExceptionsMiddleware(RequestDelegate next)
        {
            _next = next;
        }
    
        /// <summary>
        /// The method to run in the piepline
        /// </summary>
        /// <param name="context">The current context</param>
        /// <returns>As task which is running the action</returns>
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next.Invoke(context);
            }
            catch(Exception ex)
            {
                // Apply some logic based on the exception
                // Maybe log it as well - you can use DI in
                // the constructor to inject a logging service
    
                context.Response.StatusCode = //Your choice of code
                await context.Response.WriteAsync("Your message");
            }
        }
    }
    

    这里有一个“gotcha”-如果响应头已经发送,则无法编写状态代码。

    您可以在 启动 使用 Configure 方法:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
                               ILoggerFactory loggerFactory)
    {
        app.UseMiddleware<ExceptionsMiddleware>();
    }