首页 > 解决方案 > 如何从 ajax 调用异步 MVC 控制器方法

问题描述

我有一个控制器方法正在为登录的用户进行数据库查找,然后它将发送一封确认电子邮件,如下所示:

[HttpPost]
public async void ResendConfirmationEmail(string username)
{
    var user = await Usermanager.FindByNameAsync(username);
    try { SendRegistrationEmail(user); }
    catch (Exception e)
    {
        //TODO: LOGGIN EMAIL ERROR
        throw e;
    }
}

我想从这样的 ajax 函数中调用它:

var ResendRegEmail = function (identity) {
    $.ajax({
        type: "POST",
        url: "/Customer/ResendConfirmationEmail",
        data: { username: identity },
        success: function (data) {
            $("#ResendModal").modal('show');
            $("#msgSuccess").html("Email has been sent succesfully please check your email.");
        },
        error: function (request, textStatus, errorThrown) {
            $("#ResendModal").modal('show');
            $("#msgError").html(textStatus + "   " + errorThrown);
        }
    })
}

[AllowAnonymous]
public async void SendRegistrationEmail(JustAskUser user)
{ code here }

如果我删除异步,“resendCONfirmationEmail”功能会按预期工作,但业务需求是使用异步来尽可能快地保持网站流量。当前接收资源不会加载 500 错误

但随后我从“sendregistrationEmail”收到错误 - {“此时无法启动异步操作。异步操作只能在异步处理程序或模块内或页面生命周期中的某些事件期间启动。如果在执行时发生此异常一个页面,请确保该页面标记为 <%@ Page Async=\"true\" %>。此异常也可能表示尝试调用 \"async void\" 方法,这在 ASP.NET 请求中通常不受支持处理。相反,异步方法应该返回一个任务,调用者应该等待它。"}

标签: javascriptajaxasynchronousmodel-view-controller

解决方案


我相信你的问题是你打电话的地方SendRegistrationEmail。因为这个方法是异步的,所以你应该在方法名之前有一个 await 关键字。

错误消息包含所述的解决方案。

...相反,异步方法应该返回一个任务,调用者应该等待它

所以你的方法应该像这样修改:

[HttpPost]
public async void ResendConfirmationEmail(string username)
{
    var user = await Usermanager.FindByNameAsync(username);
    try 
    { 
        await SendRegistrationEmail(user); 
    }
    catch (Exception e)
    {
        //TODO: LOGGIN EMAIL ERROR
        throw e;
    }
}

推荐阅读