Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Asp.Net核心剃须刀页面异常处理会中断应用程序_C#_Exception_Asp.net Core_Task Parallel Library - Fatal编程技术网

C# Asp.Net核心剃须刀页面异常处理会中断应用程序

C# Asp.Net核心剃须刀页面异常处理会中断应用程序,c#,exception,asp.net-core,task-parallel-library,C#,Exception,Asp.net Core,Task Parallel Library,我正在构建一个Asp.NETCore2.2RazorPages应用程序。我正在编写一个全局异常处理,以避免在许多地方出现try-catch块。我看了这篇文章—— 这是你的电话号码 这是我的密码 在Startup.cs中 if(env.IsDevelopment()) { //app.UseDeveloperExceptionPage(new DeveloperExceptionPageOptions { // SourceCodeLineCount = 2 //})

我正在构建一个Asp.NETCore2.2RazorPages应用程序。我正在编写一个全局异常处理,以避免在许多地方出现try-catch块。我看了这篇文章——

这是你的电话号码

这是我的密码

Startup.cs中

if(env.IsDevelopment())
{
    //app.UseDeveloperExceptionPage(new DeveloperExceptionPageOptions {
    //    SourceCodeLineCount = 2
    //});
    //app.UseDatabaseErrorPage();
    app.UseExceptionHandler("/Error");
    app.UseStatusCodePagesWithReExecute("/Error/{0}");
    app.UseExceptionMiddleware();
} else {...}
public ExceptionMiddleware(RequestDelegate next,IMailService emailSender)
{
    _next = next;
    _emailSender = emailSender;
}

public async Task InvokeAsync(HttpContext context)
{
    try
    {
        await _next(context);
    } catch(Exception ex)
    {
        EmailException(context,ex);
    }
}

private async void EmailException(HttpContext context,Exception ex)
{
    var uaString = context.Request.Headers["User-Agent"].ToString();
    var ipAnonymizedString = context.Connection.RemoteIpAddress.AnonymizeIP();
    var userId = "Unknown";
    var profileId = "Unknown";
    if(context.User.Identity.IsAuthenticated)
    {
        userId = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
        profileId = context.User.GetUserClaim(ClaimsKey.ProfileId);
    }

    var sb = new StringBuilder($"An error has occurred on {context.Request.Host}. \r\n \r\n");
    sb.Append($"Path = {context.Request.Path} \r\n \r\n");
    sb.Append($"Error Message = {ex.Message} \r\n");
    sb.Append($"Error Source = {ex.Source} - {profileId} \r\n");

    if(ex.InnerException != null)
    {
        sb.Append($"Inner Exception = {ex.InnerException.ToString()} \r\n");
    } else
    {
        sb.Append("Inner Exception = null \r\n");
    }

    sb.Append($"Error StackTrace = {ex.StackTrace} \r\n");

    await _emailSender.SendMasterEmailAsync($"Error on {context.Request.Host}.",sb.ToString(),uaString,ipAnonymizedString,userId);

    throw ex;
}
例外middleware.cs中

if(env.IsDevelopment())
{
    //app.UseDeveloperExceptionPage(new DeveloperExceptionPageOptions {
    //    SourceCodeLineCount = 2
    //});
    //app.UseDatabaseErrorPage();
    app.UseExceptionHandler("/Error");
    app.UseStatusCodePagesWithReExecute("/Error/{0}");
    app.UseExceptionMiddleware();
} else {...}
public ExceptionMiddleware(RequestDelegate next,IMailService emailSender)
{
    _next = next;
    _emailSender = emailSender;
}

public async Task InvokeAsync(HttpContext context)
{
    try
    {
        await _next(context);
    } catch(Exception ex)
    {
        EmailException(context,ex);
    }
}

private async void EmailException(HttpContext context,Exception ex)
{
    var uaString = context.Request.Headers["User-Agent"].ToString();
    var ipAnonymizedString = context.Connection.RemoteIpAddress.AnonymizeIP();
    var userId = "Unknown";
    var profileId = "Unknown";
    if(context.User.Identity.IsAuthenticated)
    {
        userId = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
        profileId = context.User.GetUserClaim(ClaimsKey.ProfileId);
    }

    var sb = new StringBuilder($"An error has occurred on {context.Request.Host}. \r\n \r\n");
    sb.Append($"Path = {context.Request.Path} \r\n \r\n");
    sb.Append($"Error Message = {ex.Message} \r\n");
    sb.Append($"Error Source = {ex.Source} - {profileId} \r\n");

    if(ex.InnerException != null)
    {
        sb.Append($"Inner Exception = {ex.InnerException.ToString()} \r\n");
    } else
    {
        sb.Append("Inner Exception = null \r\n");
    }

    sb.Append($"Error StackTrace = {ex.StackTrace} \r\n");

    await _emailSender.SendMasterEmailAsync($"Error on {context.Request.Host}.",sb.ToString(),uaString,ipAnonymizedString,userId);

    throw ex;
}
现在,我正在我的一个page get请求中创建一个异常,如下所示

public void OnGet()
{
    throw new Exception();
}
中间件捕获异常,并在发送电子邮件后抛出该异常。然后VisualStudio说应用程序处于中断模式,VisualStudio停止。但是我的Error.cshtml.cs没有在应用程序中断和停止之前捕获异常。知道我错在哪里吗?

在他的GitHub存储库中,David Fowler指出:

在ASP.NET核心应用程序中使用async void总是不好的。避免它,永远不要做它。通常,当开发人员试图实现由控制器动作触发的fire-and-forget模式时,会使用它。如果引发异常,异步void方法将使进程崩溃

对于您描述的错误,最后一行是至关重要的——您的应用程序正在引发异常,这将导致进程崩溃

对于
EmailException
,您应该从使用
async void
切换到使用
async Task
,如下所示:

public ExceptionMiddleware(RequestDelegate next,IMailService emailSender)
{
    ...
}

public async Task InvokeAsync(HttpContext context)
{
    try
    {
        await _next(context);
    }
    catch(Exception ex)
    {
        await EmailException(context, ex); // Await.
    }
}

private async Task EmailException(HttpContext context, Exception ex) // Return a Task.
{
    ...

    throw ex;
}
如果您尝试使用
async void
的原因是您不必等待电子邮件发送后再向用户返回响应,那么您可能需要考虑使用