ASP.NET Core - 错误处理发送电子邮件并显示错误页面

时间:2017-01-09 20:51:35

标签: c# asp.net-core

我的startup.cs中有以下代码,可以通过电子邮件发送应用程序中的任何错误:

app.UseExceptionHandler(
    options =>
    {
        //options.UseDeveloperExceptionPage();
        options.Run(
            async context =>
            {
                var ex = context.Features.Get<IExceptionHandlerFeature>();
                if (ex != null)
                {
                    var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.Source}<hr />{context.Request.Path}<br />";
                    err += $"QueryString: {context.Request.QueryString}<hr />";

                    err += $"Stack Trace<hr />{ex.Error.StackTrace.Replace(Environment.NewLine, "<br />")}";
                    if (ex.Error.InnerException != null)
                        err +=
                            $"Inner Exception<hr />{ex.Error.InnerException?.Message.Replace(Environment.NewLine, "<br />")}";

                    if (context.Request.Form.Any())
                    {
                        err += "<table border=\"1\"><tr><td colspan=\"2\">Form collection:</td></tr>";
                        foreach (var form in context.Request.Form)
                        {
                            err += $"<tr><td>{form.Key}</td><td>{form.Value}</td></tr>";
                        }
                        err += "</table>";
                    }

                    await msg.SendEmailAsync(appSettings.Value.ErrorDeliveryEmailAddress, "CMP v2 error",
                        err);
                    context.Response.Redirect("/Home/Error?r=" +
                                                System.Net.WebUtility.UrlEncode(context.Request.Path + "?" +
                                                                                context.Request.QueryString));
                }
            });
        //options.UseExceptionHandler("/Home/Error");
        //options.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
    }
);

然而,它确实发现了404错误。

我如何使用:

app.UseExceptionHandler("/Home/Error");
app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");

代码,仍然将错误详细信息通过电子邮件发送到支持队列?

3 个答案:

答案 0 :(得分:1)

如果将其添加到Startup.cs中的Configure方法,则可以捕获并处理404错误:

  app.Use(async (context, next) =>
  {
    await next();
    if (context.Response.StatusCode == 404)
    {
      //handle the 404 response here
    }
  });

答案 1 :(得分:1)

我非常接近,在没有表单集合的情况下遇到错误时错误处理失败了 - 例如404等......

所以:

app.UseExceptionHandler(
    options =>
    {
        //options.UseDeveloperExceptionPage();
        options.Run(
            async context =>
            {
                var ex = context.Features.Get<IExceptionHandlerFeature>();
                if (ex != null)
                {
                    var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.Source}<hr />{context.Request.Path}<br />";
                    err += $"QueryString: {context.Request.QueryString}<hr />";

                    err += $"Stack Trace<hr />{ex.Error.StackTrace.Replace(Environment.NewLine, "<br />")}";
                    if (ex.Error.InnerException != null)
                        err +=
                            $"Inner Exception<hr />{ex.Error.InnerException?.Message.Replace(Environment.NewLine, "<br />")}";
                    // This bit here to check for a form collection!
                    if (context.Request.HasFormContentType && context.Request.Form.Any())
                    {
                        err += "<table border=\"1\"><tr><td colspan=\"2\">Form collection:</td></tr>";
                        foreach (var form in context.Request.Form)
                        {
                            err += $"<tr><td>{form.Key}</td><td>{form.Value}</td></tr>";
                        }
                        err += "</table>";
                    }

                    await msg.SendEmailAsync(appSettings.Value.ErrorDeliveryEmailAddress, "CMP v2 error",
                        err);
                    context.Response.Redirect("/Home/Error?r=" +
                                                System.Net.WebUtility.UrlEncode(context.Request.Path + "?" +
                                                                                context.Request.QueryString));
                }
            });
        //options.UseExceptionHandler("/Home/Error");
        options.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
    }
);

密钥检查为context.Request.HasFormContentType && context.Request.Form.Any()

答案 2 :(得分:1)

您可以使用以下方法实现记录器:

  public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {

        if (exception != null)
        {
            // Add the details of the Http Request if present
            var stringBuilder = new StringBuilder();
            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext != null)
            {
                var request = httpContext.Request;
                stringBuilder.Append("User: ").Append(_userManager.GetUserName(httpContext.User)).Append("<br/>")
                    .Append("Address: ").Append($"{request.Scheme}://{request.Host}{request.Path}{request.QueryString}").Append("<br/>")
                    .Append("Local IP address: ").Append(httpContext.Connection.LocalIpAddress).Append("<br/>")
                    .Append("Remote IP address: ").Append(httpContext.Connection.RemoteIpAddress).Append("<br/>");
            }
            EmailException(exception, stringBuilder);
        }
    }

    private void EmailException(Exception exception, StringBuilder stringBuilder)
    {
        BuildExceptionText(stringBuilder, "<h1>Error </h1>", exception);

        _emailSender.SendMailAsync(
            _smtpDetails.Value, new List<string> { _configuration["ErrorDeliveryEmailAddress"] },
            "System Error", stringBuilder.ToString()).ConfigureAwait(false);
    }

    private StringBuilder BuildExceptionText(StringBuilder stringBuilder, string title, Exception exception)
    {
        stringBuilder.Append(title).Append("<h2>").Append(exception.Message).Append("</h2><br/>")
           .Append(exception.Source ?? "").Append("<hr/>");
        if (exception.StackTrace != null)
        {
            stringBuilder.Append("<h3>Stack trace: </h3><br/>").Append(exception.StackTrace.Replace(Environment.NewLine, "<br/>"));
        }

        if (exception.InnerException != null)
        {
            BuildExceptionText(stringBuilder, "<h2>Inner exception </h2>", exception.InnerException);
        }

        return stringBuilder;
    }

我在这里写过:https://jdono.com/2018/05/01/asp-net-core-2-0-c-sending-errors-by-email-using-ilogger/

相关问题