使用异步操作(Task)获得404

本文关键字:获得 ActionResult 异步操作 Task | 更新日期: 2023-09-27 18:17:57

非常简单,我已经将一些同步登录操作转换为异步操作,现在它们找不到,得到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))
            {
    ...

我认为我已经做了所有需要做的,我遵循了这个:

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

编译器警告我,第一个返回视图的动作方法没有使用await关键字,所以它将同步运行。

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

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

我以前做过异步动作,我不知道为什么我今天很挣扎。

当有两个同名/重载的动作方法时,这是一个bug吗?

有人知道发生了什么事吗?

更新1

好吧,这很奇怪。

它工作时,控制器子类AsyncController,但这不是应该是如何在MVC 4+工作。

我应该在ASP使用AsyncController吗?Net MVC 4?

我正在运行MVC 5,或者应该是。我已经…年没有创建MVC 3项目了。

我需要做更多的调查,然后回来。

更新2

我有答案,但不知道为什么。我尝试了克里斯的建议,从动作中删除Async后缀,它起作用了。

奇怪的是,如上所述,当使用MVC 3中的"旧"AsyncController时,它可以工作。

我想现在就是这样了。

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

异步方法必须有东西等待。否则,它没有提示何时允许返回它的线程,因此将运行sync(在整个时间内保持线程)。这个警告只是一个警告。它让你知道你通过使方法异步而增加了开销,但实际上并没有做任何异步工作,因此,只是无缘无故地增加了开销。

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

public ActionResult BetaLoginAsync()

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

显然,在这一点上命名是尴尬的,但是你的两个方法名必须匹配,以允许路由框架对同一个URL进行回发(没有属性路由)。

然而,看到异步控制器动作以Async命名实际上是闻所未闻的。

对于其他类型的方法,通常遵循这个约定,因为它向程序员提供了他们需要等待该方法的线索。然而,通常情况下,您实际上并不直接调用控制器动作方法,这就取消了约定的好处。它也使传统的路由更加困难,除非你希望Async出现在你的url中(这是你不应该的)。

因此,我将从这两个方法中删除Async后缀。

Chris有正确的答案。当我在ASP中使用异步方法时。在asp.net MVC 4中,对于命名异步操作方法没有既定的约定。后缀只是惯例,与async无关(正如文档所述-"async"被附加到方法名之后)。不需要附加"Async",但这是编写异步方法时的约定。-正如克里斯指出,这是惯例,但不是MVC应用程序)

你的转换没有工作的原因是你错过了这一点,而使用旧的AsyncController工作的原因是旧的AsyncController依赖于async后缀。看看源代码,你就知道了。同样看一下源代码,你可以看到AsyncController现在只是一个控制器,因为控制器基类支持async。为了向后兼容,AsyncController只是留在代码库中。

创建一个新的MVC 5应用程序,添加一个模型,创建一个控制器,并勾选异步框。检查工作异步代码,也许这将帮助你找出你做错了什么。

可能MVC不匹配同名的同步和异步操作。

也就是说,BetaLoginAsync()是很好的,因为它的立场。没有异步工作要做。这是该警告的假阳性情况。

如果你喜欢,你可以使用return Task.FromResult(View());。没关系。