如何将 IActionResultExecutor<NotFoundResult> 等 IActionResultExecutor 服务添加到基于端点的路由应用程序?

How to add IActionResultExecutor services like IActionResultExecutor<NotFoundResult> to endpoint-based routing app?

如何将 IActionResultExecutor 服务(可用于 IActionResultExecutor<NotFoundResult> 等控制器操作)添加到基于端点的路由应用程序?

我正在编写一个 ASP.NET Core 3.1 应用程序,它不是一个基于控制器操作的常规应用程序,而是一个通过 app.UseEndpoints 自定义的应用程序: https://github.com/zwcloud/NancyFxViaAspNetCore/blob/646f9d820369d8fc78cf0c1f2cb18307e1851081/Nancy/NancyModule.cs#L176

它在我的实现中抛出了一个异常 endpoints.Map:

System.InvalidOperationException: 'No service for type 'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.NotFoundResult]' has been registered.'

public static Task WriteActionResult<TResult>(HttpContext context, TResult result) where TResult : IActionResult
{
    var executor = context.RequestServices.GetRequiredService<IActionResultExecutor<TResult>>();
    //**exception thrown here** System.InvalidOperationException
    if (executor == null)
    {
        throw new InvalidOperationException($"No action result executor for {typeof(TResult).FullName} registered.");
    }
    var routeData = context.GetRouteData() ?? new RouteData();
    var actionContext = new ActionContext(context, routeData, new ActionDescriptor());
    return executor.ExecuteAsync(actionContext, result);
}

public dynamic GetResult()//main logic is written here
{
    //other logic omitted
    return new NotFoundResult();
}

//this function is called in Startup.Configure()
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseEndpoints((endpoints) =>
    {
        endpoints.Map(route, async context =>
        {
            dynamic result = GetResult(context);
            await WriteActionResult(context, result);
        });
    });
}

所以我想在Startup.ConfigureServices.

中的服务中添加IActionResultExecutor<StatusCodeResult>IActionResultExecutor<NotFoundResult>和控制器动作中可用的许多其他动作结果执行器

我已经在Startup.ConfigureServices中添加了MvcCore和Mvc:

public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddMvcCore();
    services.AddMvc()
    //...
}

但我不知道哪个 class 和程序集包含此类型。没有文件指出这一点。

我失败的尝试:

我知道了。

public static Task WriteActionResult(HttpContext context, NotFoundResult result)
{
   context.Response.StatusCode = result.StatusCode;
   return context.Response.Body.FlushAsync();
}

对于像NotFoundResult这样的StatusCodeResult,我们不应该查询IActionResultExecutor而是直接写入Response。

学习自 WebApiContrib.Core's implementation

@zwcloud 我最终让它工作了。我被困在你做的地方然后通过 MVC 的 MS 源代码看看他们如何为 ObjectResult 类型做这件事。您必须构建一个 customActionResultExecutor class 来实现您的 customActionResult。执行者 class 是用 DI 注册为单例的。

Example Executor

Example Singleton DI registration for the executor