gpt4 book ai didi

c# - Azure函数中间件: How to return a custom HTTP response?

转载 作者:行者123 更新时间:2023-12-04 12:19:12 25 4
gpt4 key购买 nike

我正在探索在 .net 5 上运行的 Azure Function,并发现了新的 middleware capabilities .

我构建了一个像这样的虚拟中间件:

public sealed class ExceptionLoggingMiddleware : IFunctionsWorkerMiddleware
{
private readonly ILogger<ExceptionLoggingMiddleware> m_logger;

public ExceptionLoggingMiddleware(ILogger<ExceptionLoggingMiddleware> logger)
{
m_logger = logger;
}

public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
try
{
await next(context);
}
catch (Exception unhandledException)
{
m_logger.LogCritical(unhandledException, "Unhandled exception caught: {UnhandledException}", unhandledException.Message);
}
}
}

在我的用例中,Azure 函数是一个 HTTP 触发函数:

public sealed class StorageAccountsFunction
{
private readonly ILogger<StorageAccountsFunction> m_logger;

public StorageAccountsFunction
(
ILogger<StorageAccountsFunction> logger
)
{
m_logger = logger;
}

[Function("v1-post-storage-account")]
public async Task<HttpResponseData> CreateAsync
(
[HttpTrigger(AuthorizationLevel.Anonymous, "POST", Route = "v1/storage-accounts")]
HttpRequestData httpRequestData,
FunctionContext context
)
{
m_logger.LogInformation("Processing a request to create a new storage account");

throw new Exception("Oh no! Oh well..");
}
}

.net core 3.1 上运行的函数应用程序中,每个函数都有责任捕获未处理的异常(通过基类)并返回适当的 HTTP 状态代码。

我希望将该逻辑放在中间件中,而不是将其集中化并避免将来出现任何错误。

问题

异常被中间件正确捕获。但是,我不知道如何更改响应并返回更合适的内容,而不是我现在收到的 500 Internal Server Error

最佳答案

根据this issue ,目前还没有相关的官方实现,但他们也提到了一个“hacky 解决方法”,直到将正确的功能直接实现到 Azure 函数中

我们为 FunctionContext 创建了一个扩展方法:

internal static class FunctionUtilities
{
internal static HttpRequestData GetHttpRequestData(this FunctionContext context)
{
var keyValuePair = context.Features.SingleOrDefault(f => f.Key.Name == "IFunctionBindingsFeature");
var functionBindingsFeature = keyValuePair.Value;
var type = functionBindingsFeature.GetType();
var inputData = type.GetProperties().Single(p => p.Name == "InputData").GetValue(functionBindingsFeature) as IReadOnlyDictionary<string, object>;
return inputData?.Values.SingleOrDefault(o => o is HttpRequestData) as HttpRequestData;
}

internal static void InvokeResult(this FunctionContext context, HttpResponseData response)
{
var keyValuePair = context.Features.SingleOrDefault(f => f.Key.Name == "IFunctionBindingsFeature");
var functionBindingsFeature = keyValuePair.Value;
var type = functionBindingsFeature.GetType();
var result = type.GetProperties().Single(p => p.Name == "InvocationResult");
result.SetValue(functionBindingsFeature, response);
}
}

中间件的用法如下:

public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
try
{
await next(context);
}
catch (Exception ex)
{
if (ex.InnerException is *NameOfExceptionYouNeed* e)
{
var req = context.GetHttpRequestData();
var res = await req.ErrorResponseAsync(e.Message);
context.InvokeResult(res);
return;
}

throw;
}
}

关于c# - Azure函数中间件: How to return a custom HTTP response?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68350021/

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