如何将 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 和程序集包含此类型。没有文件指出这一点。
我失败的尝试:
在ASP.NET核心的源码中找不到,只得到NotFoundResult
的定义等
尝试过
services.TryAddSingleton(typeof(IActionResultExecutor<StatusCodeResult>));
但是当 HostBuilder.Build()
in Main
:
时抛出异常
System.ArgumentException: 'Cannot instantiate implementation type
'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.StatusCodeResult]'
for service type
'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.StatusCodeResult]'.'
尝试过
services.Add(new ServiceDescriptor(typeof(IActionResultExecutor<NotFoundResult>),
typeof(IActionResultExecutor<NotFoundResult>)));
但是当HostBuilder.Build()
in Main
时抛出异常:
我知道了。
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 注册为单例的。
如何将 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 和程序集包含此类型。没有文件指出这一点。
我失败的尝试:
在ASP.NET核心的源码中找不到,只得到
NotFoundResult
的定义等尝试过
services.TryAddSingleton(typeof(IActionResultExecutor<StatusCodeResult>));
但是当
时抛出异常HostBuilder.Build()
inMain
:System.ArgumentException: 'Cannot instantiate implementation type 'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.StatusCodeResult]' for service type 'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.StatusCodeResult]'.'
尝试过
services.Add(new ServiceDescriptor(typeof(IActionResultExecutor<NotFoundResult>), typeof(IActionResultExecutor<NotFoundResult>)));
但是当
HostBuilder.Build()
inMain
时抛出异常:
我知道了。
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 注册为单例的。