Skip to content

Best way to call a controller action method programatically and return IActionResult? #1543

@karthicksundararajan

Description

@karthicksundararajan

Hi folks,

I'm developing a open source CMS based on modular approach using ASP.NET Core RC2. I guess Areas are the best way to split the large application into small modules. Therefore, I've used areas as a modules in the CMS. Here, I would like to invoke the action method of a module (area).

1) In order to achieve that, I've created routing information manually and created action descriptor from that.

RouteContext context = new RouteContext(actionContext.HttpContext);
context.RouteData = new RouteData();
context.RouteData.Values.Add("area", moduleContext.ModuleInfo.Name);
context.RouteData.Values.Add("pageModuleId", moduleContext.PageModuleId);
context.RouteData.Values.Add("controller", moduleAction.ControllerName);
context.RouteData.Values.Add("action", moduleAction.ActionName);
context.RouteData.PushState(actionContext.RouteData.Routers[0], null, null)

var actionDescriptor = actionSelector.Select(context);
if (actionDescriptor == null)
throw new NullReferenceException("Action cannot be located, please check whether module has been installed properly");

var moduleActionContext = new ActionContext(actionContext.HttpContext, context.RouteData, actionDescriptor);

var invoker = moduleInvokerProvider.CreateInvoker(moduleActionContext, actionDescriptor as ControllerActionDescriptor);
var result = await invoker.InvokeAction() as ViewResult;null)

2) To invoke action and return IActionResult, I've used internal methods

var actionMethodInfo = _descriptor.MethodInfo;

var methodExecutor = _controllerActionMethodExecutor;

var arguments = ControllerActionExecutor.PrepareArguments(
_actionExecutingContext.ActionArguments,
actionMethodInfo.GetParameters());

Logger.ActionMethodExecuting(_actionExecutingContext, arguments);

var actionReturnValue = await ControllerActionExecutor.ExecuteAsync(
methodExecutor,
_actionExecutingContext.Controller,
arguments);

var actionResult = CreateActionResult(
actionMethodInfo.ReturnType,
actionReturnValue);

Logger.ActionMethodExecuted(_actionExecutingContext, actionResult);

return actionResult;

Question

The methods ControllerActionExecutor.PrepareArguments and ControllerActionExecutor.ExecuteAsync are internal methods of Microsoft.AspNetCore.Mvc.Internal. I guess this will changed over time when new version of ASP.NET MVC is released. Is there any better way to invoke the action method and get IActionResult?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions