【问题标题】:Trying to add Authentication to ASP.NET MVC Boilerplate template - async / await issue尝试向 ASP.NET MVC 样板模板添加身份验证 - 异步/等待问题
【发布时间】:2015-11-02 18:59:09
【问题描述】:

期待为MVC 5 Boilerplate template添加身份验证,下一段代码在它自己的original sample project中运行良好,但是当将其内容集成到样板模板中,并尝试注册新用户时,出现了冲突和出现浏览器异常,指向以下“等待”行:

// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
   if (ModelState.IsValid)
   {
      var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
      var result = await UserManager.CreateAsync(user, model.Password);
      if (result.Succeeded)
      {
         string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your account");
         ViewBag.Message = "Check your email and confirm your account, you must be confirmed "
                         + "before you can log in.";
         ViewBag.Link = callbackUrl;
         return View("Info");
      }
      AddErrors(result);
   }
   return View(model);
}

我在很多地方读到过,当发生异步问题时,人们建议将其设为同步,但就我而言,很多事情会变得不兼容。我想知道如何保持这种方法异步,因为它原来是 in the template,

【问题讨论】:

  • 首先,这是一个警告,而不是错误。它不会阻止您的应用程序工作,它只是表明您正在做一些奇怪的事情。其次,完全正确——您的GetItems 方法没有任何awaits,因此声明中的async 关键字是无用的,并且该方法将是100% 同步的——它没有理由返回a Task 要么。
  • 浏览器给出了一个例外,我不能忽视它,请阅读整个问题,包括模板讨论。
  • 您是否将警告作为错误进行编译?
  • 您能否使用minimal reproducible example 更新您的帖子以及您面临的确切错误。帖子中提到的编译时警告不太可能是您运行网站时显示的错误。
  • 好吧,您没有发布任何异常,那么我们应该如何帮助您解决您遇到的异常?您发布的消息是编译器警告,而不是运行时异常。它与突出显示的行无关(除非它以某种方式参与 JIT 编译),因此您的真正错误更有可能仍然存在,以某种方式隐藏。删除有问题的代码(从您的绝对同步方法中删除 async),然后重试 - 也许您会得到真正的错误。

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


【解决方案1】:

你的GetItems 不需要await,所以它不应该是async。只需将签名更改为:

private List<SyndicationItem> GetItems(CancellationToken cancellationToken)

并将调用代码更改为:

await GetItems(token);

到:

GetItems(token);

【讨论】:

  • 如果我使用 Andrii 提出的 TaskCompletionSource 怎么办,它对 FeedServices.cs 有效,但 AccountController 方法仍然遇到同样的问题。
  • 我读过很多帖子,据说可以将异步方法转换为同步方法,我想知道为什么模板作者将它们设为异步。 accountController 由 Rick Anderson 制作:asp.net/mvc/overview/security/…
  • @Sami-L 如果你有异步工作要做,你会想要一个异步控制器。您没有正在做的任何异步工作。
  • @Sami-L async 关键字不是方法签名的一部分。它只允许您在方法主体中使用await,仅此而已。它还包装任何异常并在任务中返回,但您可以手动执行此操作。因此,如果它是 public 接口的一部分,那么在保留 Task&lt;Whatever&gt; 返回值的同时删除 async 是完全可以的(使用 Task.FromResult(...) 将实际返回值包装在已完成的任务中)。如果只是一些私人方法,请不要打扰,反正是骗人的;你是在说“当然,这个方法是完全异步的”,但实际上不是。
  • @Sami-L: 等等,现在你的方法是使用await???在您最初的问题中,您询问的是您收到的编译器警告,因为您的方法没有使用等待。现在问题已经 100% 不同了。
【解决方案2】:

感谢Nikita1315的帮助,我发现startup.cs文件中缺少下一个配置语法:

       ConfigureAuth(app);

所以启动类看起来像:

    public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureContainer(app);
        ConfigureAuth(app);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    }
}

所以,只要我添加了这个配置,并且不修改任何异步方法,我就可以注册我的第一个用户。

【讨论】:

    猜你喜欢
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2017-08-24
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多