获取具有异步操作的404(Task <actionresult>)</actionresult>

时间:2014-08-14 14:50:10

标签: c# asp.net-mvc asp.net-mvc-4 asynchronous

很简单,我已经将一些同步登录操作转换为异步,现在找不到它们,获得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关键字时,它根本就不会编译。编译器说,从ViewResult调用返回的类型View无法隐式转换为Task<ActionResult>类型。

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

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

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

有谁知道发生了什么事?

更新1

好的,这很奇怪。

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

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

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

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

更新2

我有一个答案,但没有真正理解为什么。我尝试了克里斯关于从行动中删除Async后缀的建议,并且它有效。

奇怪的是,如上所述,它在使用MVC 3中的“旧”AsyncController时有效。

我想这就是它现在的样子。

3 个答案:

答案 0 :(得分:4)

异步方法必须具有等待的功能。否则,它没有提示何时允许返回其线程,因此将运行同步(在整个时间保持线程)。警告就是:警告。它让你知道你通过使方法异步但不实际做任何异步工作来增加开销,因此,只是无缘无故地增加开销。

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

public ActionResult BetaLoginAsync()

然后,它将编译而不会出现错误或警告。

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

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

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

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

答案 1 :(得分:3)

克里斯有正确的答案。当我写Using Asynchronous Methods in ASP.NET MVC 4时,没有建立用于命名异步操作方法的约定。后缀只是约定而与async无关(因为文档说明 - &#34; Async&#34;附加到方法名称。追加&#34; Async&#34;不是必需的,但是编写异步方法时的惯例.-正如克里斯指出的那样是惯例,而不是MVC应用程序

您的转换无法正常工作的原因是您错过了这一点,并且使用旧的AsyncController工作的原因是旧的AsyncController依赖于异步后缀。查看源代码,您可以看到。另外看一下源代码,你可以看到AsyncController现在只是一个控制器,因为控制器基类支持async。 AsyncController刚刚留在代码库中以实现向后兼容。

创建一个新的MVC 5应用程序,添加模型,创建一个控制器并检查异步框。检查工作异步代码,这可能会帮助您弄清楚您做错了什么。异步MVC非常常见并且被广泛使用。

答案 2 :(得分:1)

也许MVC没有匹配同名和异步动作同名。

那就是说,BetaLoginAsync()现在很好。没有异步工作要做。这是警告的假阳性案例。

如果您愿意,可以使用return Task.FromResult(View());。这没关系。