Azure 函数中间件:如何返回自定义 HTTP 响应?
Posted
技术标签:
【中文标题】Azure 函数中间件:如何返回自定义 HTTP 响应?【英文标题】:Azure Function Middleware: How to return a custom HTTP response? 【发布时间】:2021-09-21 18:38:35 【问题描述】:我正在探索在 .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
?
【问题讨论】:
【参考方案1】:根据this issue,目前没有关于此的官方实现,但他们也提到了一个“hacky workaround”,直到将正确的功能直接实现到 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;
【讨论】:
以上是关于Azure 函数中间件:如何返回自定义 HTTP 响应?的主要内容,如果未能解决你的问题,请参考以下文章
发布函数时未返回 Azure Functions V2 Http 错误代码内容