【问题标题】:Task async controller method does not hit任务异步控制器方法未命中
【发布时间】:2013-12-11 20:43:03
【问题描述】:

所以,我们有一个 MVC 项目,它已经通过不同版本的 MVC 从 1 升级到 4。

现在我们有了一个控制器方法:

public async Task<ActionResult> IndexAsync()

所以如果我们去http://somedomain.xyz/WhicheverController http://somedomain.xyz/WhicheverController/Index,我们会收到一个404。

http://somedomain.xyz/WhicheverController/IndexAsync 路由到方法就好了。

我们的路由出了什么问题?

【问题讨论】:

  • 你的路由在哪里?没有将名称映射到异步方法的约定

标签: c# asp.net-mvc routes asp.net-mvc-routing async-await


【解决方案1】:

我相信,如果您改为从 AsyncController 派生控制器,您的示例将起作用。

public class MyController:AsyncController
{
    public async Task<ActionResult> IndexAsync()
    {
       return View(); //view called "Index.cshtml", not "IndexAsync.cshtml"
    }
}

所以现在你可以在没有Async 后缀的情况下点击~/My/Index,尽管Async 出现在控制器名称中。

这是之前 MVC 异步控制器方法的遗物,通常需要 IndexComplete 方法才能工作,但是对于基于任务的异步控制器方法,不需要匹配的 XxxxComplete 方法,而是 Async 约定被观察到。

AsyncController 的实际实现相当稀疏:

public abstract class AsyncController : Controller
{
}

所以在 MVC 堆栈的某个地方,测试了控制器的类型,并开启了特殊的路由魔法。

【讨论】:

    【解决方案2】:

    没有将异步操作映射到带有Async 后缀的方法的约定。如果您想在动作名称中使用Async 后缀,则必须修改您的路线。

    只需将方法的返回类型更改为async Task&lt;ActionResult&gt; 就足以异步执行操作。

    Async 后缀只是一个命名约定。任何 MVC 框架都不期望或强制执行它。

    示例

    以下操作使用默认路由异步工作

    public class HomeController : Controller
    {
        public async Task<ActionResult> Index()
        {
            await Task.Delay(1000);
            ViewBag.Message = "Modify this template to jump-start blah .. blah";
    
            return View();
        }
        ...
    }
    
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", 
                                id = UrlParameter.Optional }
            );
        }
    }
    

    【讨论】:

      【解决方案3】:

      路由工作得很好,在 asp.net mvc 5 中,您不再需要 Async 后缀来执行操作,您应该删除它。

      此约定仅用于链接异步执行一项作业的两个操作(操作方法和操作结果)。使用 asp.net mvc 5 中的新异步模型,您不再需要此异步约定。就像从 AsyncController 继承一样。

      【讨论】:

      • 是的,但是为什么约定不再起作用了?顺便提一句。我们在 MVC4 上
      • 我认为当您从 AsyncController 派生时,此约定有效。在 asp.net mvc 5 中,您不需要这样做,并且路由与其他操作一样工作。
      • 根据 Using Asynchronous Methods in ASP.NET MVC 4 (asp.net/mvc/tutorials/mvc-4/…),“附加‘Async’不是必需的,但这是编写异步方法时的约定。”
      • 是的,这是编写异步方法的惯例,而不是路由。查看以下控制器:github.com/RickAndMSFT/Async-ASP.NET/blob/master/Mvc4Async/…。假设我去 /Home/Products,那么应该执行哪些操作? ProductsAsync 还是 Products?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 2020-02-11
      • 2015-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多