ASP.NET Core Resolve Controller 并按名称调用 Action
ASP.NET Core Resolve Controller and call Action by name
我有一个通用的捕获所有 controller/action 接收文件,解析 json 内容并从中找出要调用的控制器名称和操作名称。
这是我以前的 .NET Framework(旧 ASP)实现,效果很好:
public async Task<ActionResult> Run(PackingSlip packingSlip, IEnumerable<HttpPostedFileBase> files)
{
var controllerName = packingSlip.service_name;
var actionName = packingSlip.service_object;
// get the controller
var ctrlFactory = ControllerBuilder.Current.GetControllerFactory();
var ctrl = ctrlFactory.CreateController(this.Request.RequestContext, controllerName) as Controller;
var ctrlContext = new ControllerContext(this.Request.RequestContext, ctrl);
var ctrlDescAsync = new ReflectedAsyncControllerDescriptor(ctrl.GetType());
ctrl.ControllerContext = ctrlContext;
// get the action
var actionDesc = ctrlDescAsync.FindAction(ctrlContext, actionName);
// execute
ActionResult result;
if (actionDesc is AsyncActionDescriptor actionDescAsync)
result = await Task.Factory.FromAsync((asyncCallback, asyncState) => actionDescAsync.BeginExecute(ctrlContext, new Dictionary<string, object> { { "packingSlip", packingSlip }, { "files", files } }, asyncCallback, asyncState), asyncResult => actionDescAsync.EndExecute(asyncResult), null) as ActionResult;
else
result = actionDesc.Execute(ctrlContext, new Dictionary<string, object> { { "packingSlip", packingSlip }, { "files", files } }) as ActionResult;
// return the other action result as the current action result
return result;
}
现在有了 ASP.NET Core(或 .NET 5),ControllerBuilder
不再存在,其中大部分都发生了变化。
我尝试注入 IControllerFactory
并使用它,但找不到使用它来调用已知“controllerName”和“actionName”的动作的正确方法。它还应该像以前一样,确定它是否是一个异步操作,并采取相应的行动。
自己找到答案。
AspCore 有一个隐藏的几乎没有记录的扩展方法,它在 DI 容器中注册控制器:AddControllersAsServices.
services.AddMvc().AddControllersAsServices();
然后你可以使用IServiceProvider
来解析你的控制器。
我有一个通用的捕获所有 controller/action 接收文件,解析 json 内容并从中找出要调用的控制器名称和操作名称。
这是我以前的 .NET Framework(旧 ASP)实现,效果很好:
public async Task<ActionResult> Run(PackingSlip packingSlip, IEnumerable<HttpPostedFileBase> files)
{
var controllerName = packingSlip.service_name;
var actionName = packingSlip.service_object;
// get the controller
var ctrlFactory = ControllerBuilder.Current.GetControllerFactory();
var ctrl = ctrlFactory.CreateController(this.Request.RequestContext, controllerName) as Controller;
var ctrlContext = new ControllerContext(this.Request.RequestContext, ctrl);
var ctrlDescAsync = new ReflectedAsyncControllerDescriptor(ctrl.GetType());
ctrl.ControllerContext = ctrlContext;
// get the action
var actionDesc = ctrlDescAsync.FindAction(ctrlContext, actionName);
// execute
ActionResult result;
if (actionDesc is AsyncActionDescriptor actionDescAsync)
result = await Task.Factory.FromAsync((asyncCallback, asyncState) => actionDescAsync.BeginExecute(ctrlContext, new Dictionary<string, object> { { "packingSlip", packingSlip }, { "files", files } }, asyncCallback, asyncState), asyncResult => actionDescAsync.EndExecute(asyncResult), null) as ActionResult;
else
result = actionDesc.Execute(ctrlContext, new Dictionary<string, object> { { "packingSlip", packingSlip }, { "files", files } }) as ActionResult;
// return the other action result as the current action result
return result;
}
现在有了 ASP.NET Core(或 .NET 5),ControllerBuilder
不再存在,其中大部分都发生了变化。
我尝试注入 IControllerFactory
并使用它,但找不到使用它来调用已知“controllerName”和“actionName”的动作的正确方法。它还应该像以前一样,确定它是否是一个异步操作,并采取相应的行动。
自己找到答案。
AspCore 有一个隐藏的几乎没有记录的扩展方法,它在 DI 容器中注册控制器:AddControllersAsServices.
services.AddMvc().AddControllersAsServices();
然后你可以使用IServiceProvider
来解析你的控制器。