我们可以将 Func<T,TResult> 传递给 .Net core 5 中的中间件来执行吗?

Posted

技术标签:

【中文标题】我们可以将 Func<T,TResult> 传递给 .Net core 5 中的中间件来执行吗?【英文标题】:Can we pass a Func<T,TResult> to a middleware in .Net core 5 to execute? 【发布时间】:2021-10-31 18:12:49 【问题描述】:

所以,我正在尝试创建一个将异常转换为特定错误的中间件。

现在有两个项目想要实现相同的中间件,但有自己的逻辑来处理错误消息。

我想将处理异常的方式抽象到每个项目中,这个中间件所做的工作只是将 ErrorResponse 转换为 json 并发送回用户。

中间件代码是

public class ExceptionHandlingMiddleware

    public RequestDelegate requestDelegate;
    private readonly Func<Exception, ErrorResponse> _errorResponse;

    public ExceptionHandlingMiddleware(RequestDelegate requestDelegate, Func<Exception, ErrorResponse> errorResponse)
    
        this.requestDelegate = requestDelegate;
         _errorResponse = errorResponse;
    
    public async Task Invoke(HttpContext context)
    
        try
        
            await requestDelegate(context);
        
        catch (Exception ex)
        
            var error = _errorResponse(ex);
            await HandleException(context, error);
        
    
    private static Task HandleException(HttpContext context, ErrorResponse error)
    
        var errorMessage = JsonConvert.SerializeObject(error);

        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

        return context.Response.WriteAsync(errorMessage);
    

我创建了一个扩展方法

        public static IApplicationBuilder UseExceptionHandling(this IApplicationBuilder app, Func<Exception, ErrorResponse> errorResponse)
    
        return app.UseMiddleware<ExceptionHandlingMiddleware>(errorResponse);
    

现在我像这样使用它,但这给了我一个未设置为对象实例的对象引用

  app.UseExceptionHandling(HandleException);

    private static ErrorResponse HandleException(Exception ex)
    
        return new ErrorResponse()  Code = "Foo" ;
    

并且 _errorResponse(在中间件中)似乎为空。

如果这是错误的做法,请告诉我。

【问题讨论】:

你有NullReferenceException吗?如果_errorResponse 为空,那么var error = _errorResponse(ex) 行应该抛出异常。 是的,var error = _errorResponse(ex); 抛出 NullReferenceException。知道如何解决这个问题吗?为什么当被告知使用中间件app.UseExceptionHandling(HandleException); 时传递 _errorResponse 为 null 你试过调试代码吗?尝试在 UseExceptionHandling 方法中设置断点,并找出那里的 errorResponse 是否也为空。 【参考方案1】:

我觉得你想捕获异常和自定义错误信息的中间件是错误的。

原因:

假设控制器中有一个Exception,虽然你传给ExceptionHandlingMiddleware,但是当你执行public async Task Invoke(HttpContext context)方法的时候,你可以确定catch (Exception ex)就是你传入的那个Exception是一样的吗?

因此您无需费力如何将 Func 传递给中间件。

建议:

下面的文章应该对你有用。

ASP.NET Core 3.1 - Global Error Handler Tutorial

【讨论】:

首先要感谢您的回答,但是如果您看到异常部分的处理,则有switch声明。如果有任何新异常被添加到应用程序中,则需要在此处处理,现在开发人员可以在响应中写入任何对象。我想将其抽象为仅返回标准错误响应的方法,然后在多个项目中使用它。

以上是关于我们可以将 Func<T,TResult> 传递给 .Net core 5 中的中间件来执行吗?的主要内容,如果未能解决你的问题,请参考以下文章

Expression<Func<T,TResult>>和Func<T,TResult>

Expression<Func<T,TResult>>和Func<T,TResult> 与AOP与WCF

如何设置属性选择器的值 Expression<Func<T,TResult>>

Action 和 Func

通用异步函数

关于内置委托的用法