使用异步操作(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
时,它可以工作。
我想现在就是这样了。
异步方法必须有东西等待。否则,它没有提示何时允许返回它的线程,因此将运行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());
。没关系。