gpt4 book ai didi

c# - 是否可以使用 UseExceptionHandler() 和 ExceptionHandler 选项来配置 "handle web api requests specifically"?

转载 作者:行者123 更新时间:2023-12-02 11:01:52 26 4
gpt4 key购买 nike

我想返回有关错误的具体 json 信息。

我有自定义中间件的解决方案,但我不明白如何使用标准 ExceptionHandler 选项执行相同的操作:

我正在尝试:

app.UseExceptionHandler(
new ExceptionHandlerOptions() {
ExceptionHandlingPath=new PathString("/Error"),
ExceptionHandler = async context =>
{
var ex = context.Features.Get<IExceptionHandlerFeature>().Error;
var originalFeature = context.Features.Get<IExceptionHandlerPathFeature>();
bool isApiCall = false;
if (originalFeature!=null && originalFeature.Path!=null && originalFeature.Path.Contains("Api/")) // TODO: regex
{
isApiCall = true;
}

if (isApiCall)
{
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(AspCoreManager.GetErrorActionJson(ex, "", true));
}
else
{
await /* ??? how to get the "_next" delegate (from pipeline) or how to abort a pipeline and response with an "/Error" page */;
}
}
});

所以我不明白如何返回到标准处理 - 调用“/Error”页面。

这是自定义中间件,可以完成我需要的所有工作,但我有神奇的 _next 委托(delegate)来完成所有工作:

// modified and simplified https://github.com/aspnet/Diagnostics/blob/master/src/Microsoft.AspNetCore.Diagnostics/ExceptionHandler/ExceptionHandlerMiddleware.cs
public class MyExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly ExceptionHandlerOptions _options;
private readonly ILogger _logger;
private readonly Func<object, Task> _clearCacheHeadersDelegate;
private readonly DiagnosticSource _diagnosticSource;
private readonly ApplicationSettings applicationSettings;

public MyExceptionHandlerMiddleware(
RequestDelegate next,
ILoggerFactory loggerFactory,
IOptions<ExceptionHandlerOptions> options,
DiagnosticSource diagnosticSource,

)
{
_next = next;
_options = options.Value;
_logger = loggerFactory.CreateLogger<ExceptionHandlerMiddleware>();
_clearCacheHeadersDelegate = ClearCacheHeaders;
_diagnosticSource = diagnosticSource;
if (_options.ExceptionHandler == null)
{
_options.ExceptionHandler = _next;

}
}

public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
if (context.Response.HasStarted)
{
throw;
}
PathString originalPath = context.Request.Path;
bool isApiCall = false;
if (originalPath.HasValue && originalPath.Value.Contains("Api/"))
{
isApiCall = true;
}

if (_options.ExceptionHandlingPath.HasValue)
{
context.Request.Path = _options.ExceptionHandlingPath;
}
try
{
context.Response.Clear();
var exceptionHandlerFeature = new ExceptionHandlerFeature()
{
Error = ex,
Path = originalPath.Value,
};
context.Features.Set<IExceptionHandlerFeature>(exceptionHandlerFeature);
context.Features.Set<IExceptionHandlerPathFeature>(exceptionHandlerFeature);
context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; // 500
context.Response.OnStarting(_clearCacheHeadersDelegate, context.Response);
if (isApiCall)
{
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(AspCoreManager.GetErrorActionJson(ex));
}
else
{
await _options.ExceptionHandler(context);
}

return;
}
catch (Exception ex2)
{
// Suppress secondary exceptions
}
finally
{
context.Request.Path = originalPath;
}
throw; // Re-throw the original if we couldn't handle it
}
}

private Task ClearCacheHeaders(object state)
{
var response = (HttpResponse)state;
response.Headers[HeaderNames.CacheControl] = "no-cache";
response.Headers[HeaderNames.Pragma] = "no-cache";
response.Headers[HeaderNames.Expires] = "-1";
response.Headers.Remove(HeaderNames.ETag);
return Task.CompletedTask;
}
}

最佳答案

您可以通过以下方式实现两全其美:

const string errorPath = "/Error";

app.UseExceptionHandler(errorPath);
app.Use(async (ctx, next) =>
{
if (ctx.Request.Path == errorPath)
{
var ex = ctx.Features.Get<IExceptionHandlerFeature>().Error;
var originalFeature = ctx.Features.Get<IExceptionHandlerPathFeature>();

if (originalFeature != null && originalFeature.Path != null && originalFeature.Path.Contains("Api/")) // TODO: regex
{
ctx.Response.ContentType = "application/json";
await ctx.Response.WriteAsync(AspCoreManager.GetErrorActionJson(ex));
return;
}
}

// Request.Path is not for /Error *or* this isn't an API call.
await next();
});

在此示例中,我们重用所有现有的 UseExceptionHandler 逻辑进行日志记录、路径重写等,然后使用一个额外的中间件来拦截对 /Error 的调用,检查是否是 API 调用,然后做出相应 react 。

关于c# - 是否可以使用 UseExceptionHandler() 和 ExceptionHandler 选项来配置 "handle web api requests specifically"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55472678/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com