简体   繁体   English

获取具有异步操作的404(任务 <ActionResult> )

[英]Getting a 404 with asynchronous action (Task<ActionResult>)

Very simply, I've converted some synchronous login actions to asynchronous and now they're not found, getting 404. 很简单,我已经将一些同步登录操作转换为异步,现在找不到它们,获得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))
            {
    ...

I thought I'd done all that's needed, I followed this: 我以为我已经完成了所有需要,我遵循了这个:

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

The compiler is warning me that the first action method that just returns a view isn't using the await keyword, so it will run synchronously. 编译器警告我,仅返回视图的第一个操作方法不使用await关键字,因此它将同步运行。

The problem is that when I remove the async keyword, it then doesn't compile at all. 问题是,当我删除async关键字时,它根本不会编译。 Compiler says that the type ViewResult returned from the call to View cannot be implicitly converted to type Task<ActionResult> . 编译器说从调用View返回的类型ViewResult不能隐式转换为Task<ActionResult>类型。

Now, if I make it synchronous but leave my HttpPost post-back login validation method asynchronous , then MVC routing doesn't call it when I click the submit button, instead it posts to the synchronous version that just returns the view!! 现在,如果我使它同步但让我的HttpPost回发后登录验证方法异步 ,那么当我点击提交按钮时MVC路由不会调用它,而是发布到只返回视图的同步版本!

I've worked with asynchronous actions before, I don't know why I'm struggling today. 之前我曾经使用异步操作,我不知道为什么我今天都在挣扎。

Is this a bug when there are two action methods with the same name/overloaded?? 当有两个具有相同名称/重载的操作方法时,这是一个错误吗?

Does anyone know what's going on? 有谁知道发生了什么?

Update 1 更新1

Okay, so this is weird. 好的,所以这很奇怪。

It works when the controller subclasses AsyncController but this is not supposed to be how it works in MVC 4+. 当控制器子类化AsyncController时,它可以工作,但这不应该是它在MVC 4+中的工作方式。

Should I use AsyncController at ASP.NET MVC 4? 我应该在ASP.NET MVC 4上使用AsyncController吗?

I'm running MVC 5, or supposed to be. 我正在运行MVC 5,或者应该是。 I haven't created an MVC 3 project for ...years. 我还没有创建一个MVC 3项目......。

I'll need to do some more investigating and come back. 我需要做更多的调查并回来。

Update 2 更新2

I have an answer, but no real understanding of why. 我有一个答案,但没有真正理解为什么。 I tried Chris' suggestion of removing the Async suffix from the actions and it worked. 我尝试了克里斯关于从动作中删除Async后缀的建议并且它有效。

The strange thing is that, as above, it works when using the 'old' AsyncController from MVC 3. 奇怪的是,如上所述,它在使用MVC 3中的“旧” AsyncController时起作用。

I guess that's just how it is now. 我猜这就是现在的样子。

An asynchronous method must have something to wait on. 异步方法必须要等待 Otherwise, it has no cue for when it's allowed to return its thread and will therefore run sync (hold on to the thread the entire time). 否则,它没有提示何时允许返回其线程,因此将运行同步(在整个时间保持线程)。 The warning is just that: a warning. 警告就是:警告。 It's letting you know that you're adding overhead by making the method async but not actually doing any asynchronous work and, therefore, are just adding overhead for no reason. 它让你知道你通过使方法异步但不实际做任何异步工作来增加开销,因此,只是无缘无故地增加开销。

The reason you got an error with removing async is that you're still returning a Task<ActionResult> . 删除async出错的原因是您仍然返回Task<ActionResult> So if you want to remove async, you actually need to change the method definition to: 因此,如果要删除异步,实际上需要将方法定义更改为:

public ActionResult BetaLoginAsync()

Then, it will compile without error or warning. 然后,它将编译没有错误或警告。

Obviously the naming is awkward at that point, but your two method names must match up to allow the routing framework to do a postback to the same URL (without attribute routing). 显然,此时命名很尴尬,但是您的两个方法名称必须匹配,以允许路由框架回发到同一个URL(没有属性路由)。

However, it's actually pretty unheard of to see async controller actions named with Async . 但是,看到以Async命名的异步控制器操作实际上是闻所未闻的。

It's common to follow that convention for other types of methods, because it provides a clue to the programmer that they need to await the method. 对于其他类型的方法遵循该约定是很常见的,因为它为程序员提供了他们需要等待该方法的线索。 However, you don't actually call controller actions methods directly, typically, which removes the benefit of the convention. 但是,您实际上并不直接调用控制器操作方法,这通常会消除约定的好处。 It also makes traditional routing more difficult unless you like Async showing up in your URLs (which you shouldn't). 它还会使传统路由更加困难,除非您希望Async显示在您的URL中(您不应该这样做)。

So, I would just remove the Async suffix from both methods. 所以,我只是从两种方法中删除Async后缀。

Chris has the right answers. 克里斯有正确的答案。 When I wrote Using Asynchronous Methods in ASP.NET MVC 4 there was no established convention for naming async action methods. 当我在ASP.NET MVC 4中编写使用异步方法时,没有建立用于命名异步操作方法的约定。 The suffix is just convention and has nothing to do with async (as the document states - "Async" was appended to the method name. Appending "Async" is not required but is the convention when writing asynchronous methods.- As Chris points out that's the convention, but not for MVC apps ) 后缀只是约定而与async无关(因为文档状态 - “Async”被附加到方法名称。 附加“Async”不是必需的,但是在编写异步方法时是惯例.-正如Chris指出的那样惯例,但不适用于MVC应用程序

The reason your conversion didn't work is you missed that point, and the reason using the old AsyncController works, is the old AsyncController depended on the async suffix. 您的转换不起作用的原因是您错过了这一点,并且使用旧的AsyncController工作的原因是旧的AsyncController依赖于异步后缀。 Look at the source code and you can see that. 查看源代码,您可以看到。 Also look at the source code and you can see an AsyncController just a controller now since the controller base class supports async. 另外看一下源代码,你可以看到AsyncController现在只是一个控制器,因为控制器基类支持async。 AsyncController was just left in the code base for backward compatibility. 为了向后兼容,AsyncController只是留在代码库中。

Create a new MVC 5 app, add a model, create a controller and check the async box. 创建一个新的MVC 5应用程序,添加模型,创建一个控制器并检查异步框。 Examine the working async code and maybe that will help you figure out what you're doing wrong. 检查工作异步代码,这可能会帮助你弄清楚你做错了什么。 Async MVC is very common and widely used. 异步MVC非常常见并且被广泛使用。

Maybe MVC doesn't match up a sync and an async action with the same name. 也许MVC不匹配具有相同名称的同步和异步操作。

That said, BetaLoginAsync() is fine as it stands. 也就是说, BetaLoginAsync()很好。 There is no async work to do. 没有异步工作要做。 This is a false-positive case of that warning. 这是该警告的假阳性案例。

You could use return Task.FromResult(View()); 你可以使用return Task.FromResult(View()); if you like. 如果你喜欢。 It doesn't matter. 没关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM