使用异步操作获取404(Task <ActionResult>)

Luk*_*ett 5 c# asp.net-mvc asynchronous asp.net-mvc-4

很简单,我已经将一些同步登录操作转换为异步,现在找不到它们,获得404.

    public async Task<ActionResult> BetaLoginAsync()
    {            
        return View();
    }

    [HttpPost]
    public async Task<ActionResult> BetaLoginAsync(Models.Authentication.SimpleLoginModel loginModel, string returnUrl)
    {
        if (this.ModelState.IsValid)
        {
            if (await this.ValidateCredentialsAsync(loginModel))
            {
    ...
Run Code Online (Sandbox Code Playgroud)

我以为我已经完成了所有需要,我遵循了这个:

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

编译器警告我,只返回视图的第一个操作方法不使用await关键字,因此它将同步运行.

问题是,当我删除async关键字时,它根本就不会编译.编译器说ViewResult从调用返回的类型View不能隐式转换为类型Task<ActionResult>.

现在,如果我使它同步但让我HttpPost的回发后登录验证方法异步,那么当我点击提交按钮时MVC路由不会调用它,而是发布到只返回视图的同步版本!

之前我曾经使用异步操作,我不知道为什么我今天都在挣扎.

当有两个具有相同名称/重载的操作方法时,这是一个错误吗?

有谁知道发生了什么?

更新1

好的,所以这很奇怪.

当控制器子类化AsyncController时,它可以工作,但这不应该是它在MVC 4+中的工作方式.

我应该在ASP.NET MVC 4上使用AsyncController吗?

我正在运行MVC 5,或者应该是.我还没有创建一个MVC 3项目.......

我需要做更多的调查并回来.

更新2

我有一个答案,但没有真正理解为什么.我试着克里斯建议Async从动作中删除后缀并且它有效.

奇怪的是,如上所述,它在使用AsyncControllerMVC 3中的"旧"时起作用.

我猜这就是现在的样子.

Chr*_*att 4

异步方法必须有等待的东西。否则,它不会提示何时允许返回其线程,因此将运行同步(始终保持线程)。警告就是这样:警告。它让您知道,您通过使方法异步增加了开销,但实际上并没有执行任何异步工作,因此,只是无缘无故地增加了开销。

删除时出错的原因async是您仍然返回Task<ActionResult>. 所以如果你想删除 async,你实际上需要将方法定义更改为:

public ActionResult BetaLoginAsync()
Run Code Online (Sandbox Code Playgroud)

然后,它将编译,没有错误或警告。

显然,此时的命名很尴尬,但是两个方法名称必须匹配才能允许路由框架回发到同一 URL(没有属性路由)。

然而,实际上很少听说过以 命名的异步控制器操作Async

对于其他类型的方法,通常遵循该约定,因为它向程序员提供了他们需要等待该方法的线索。但是,通常您实际上并不直接调用控制器操作方法,这消除了约定的好处。它还使传统路由变得更加困难,除非您喜欢Async出现在 URL 中(您不应该这样做)。

所以,我只是Async从这两种方法中删除后缀。

  • 这不是一个错误。这可能会产生误导,但其中的每一部分代码都会运行。 (2认同)