首页 > 解决方案 > ExecuteResultAsync(ActionContext) 方法的用途是什么

问题描述

在 webapi/mvc 控制器中,aController将返回一个ActionResult<T>类型,并且它有一个ExecuteResultAsync(ActionContext)方法。

方法的用途是ExecuteResultAsync(ActionContext)什么?MVC 将如何使用该方法?其中,ActionContext参数来自哪里?从Http请求?

标签: c#asp.netasp.net-core

解决方案


方法的用途是ExecuteResultAsync(ActionContext)什么?

  1. IActionResult控制器操作方法返回的结果(对象)。ASP.NET Core 通过调用该IActionResult::ExecuteResultAsync(ActionContext)方法来执行这个结果。
  2. Action 方法可能会返回不同类型的IActionResult,例如JsonResult(执行时向客户端发送 json)、BadRequestResult(执行时发送400响应)等。
  3. 您还可以创建自己的IActionResult. 请注意,该ExecuteResultAsync(ActionContext)方法应将字节写入 HTTP Response。例如,我创建了一个自定义IActionResult返回 CSV 文件供您参考。这是一个简单的实现,不包含太多复杂的逻辑。

    一些动作结果相当复杂,它们引入了一个新的IActionResultExecutor<TResult>接口来处理这些过程,例如,ObjectResult使用一个IActionResultExecutor<ObjectResult>来执行该操作。创建自己的实现时,是否使用 anIActionResultExecutor<ObjectResult>取决于您。

MVC 将如何使用该方法?

  1. WebApp 开发人员不需要IActionResult::ExecuteResultAsync(ActionContext)手动调用此方法。这是一个将由 MVC/RazorPage 子系统调用的方法。
  2. 如果你有兴趣,整个过程是:
    • 收到一个即将到来的请求
    • 将当前请求与预定义的路由(路由表或图表)相匹配。如果匹配:
      • 我们知道控制器名称、动作名称和其他路由数据。
      • 由于我们已经知道控制器名称和操作名称,ASP.NET Core 会生成一个ActionDescriptor描述目标 C# 操作方法的实例,例如参数。
    • 由于 ASP.NET Core 已经知道 Controller/Action 和路由数据,它会创建一个实例IActionInvoker来调用该 action 方法 pipline(包括过滤器,有关更多详细信息,请参阅官方文档):
      • Action 方法返回一个实例IActionResult
      • 在调用 之前IActionResult::ExecuteResultAsync(ActionContext),调用 Result FiltersOnResultExecuting()方法。
      • 调用IActionResult::ExecuteResultAsync(ActionContext)
      • 之后,调用 Result FiltersOnResultExecuted()方法。

ActionContext 参数来自哪里?来自 Http 请求?

首先,HttpContext由底层服务器构建。它包含一个Request模仿 HTTP 请求的属性。

接下来,我们将在选择动作后得到另外两个对象:

  • RouteData:路线数据,例如当前area名称,当前page名称等
  • ActionDescriptor:与当前路由匹配的当前动作的描述。

有了以上三个对象,ASP.NET Core 就ActionContext通过简单的 new it 创建了。例如,IRouter基于 - 的路由系统创建一个 actionContext 如下:(参见源代码

// create action context
var actionContext = new ActionContext(context.HttpContext, routeData, actionDescriptor);

// create action invoker
var invoker = _actionInvokerFactory.CreateInvoker(actionContext);
if (invoker == null){ throw ...;}

// invoke the pipeline
return invoker.InvokeAsync(); 

推荐阅读