I need to send an asynchronous email from an Async action. I do not understand why the following error is happening, being that I use this same class in other projects and use the same form only without errors, everything quiet.
Error:
The asynchronous action method 'EsqueciMinhaSenhaAsync' returns a Task, which cannot be executed synchronously.
Action:
[AllowAnonymous]
[HttpPost, ValidateAntiForgeryToken]
public async Task<ActionResult> EsqueciMinhaSenhaAsync(UsuarioEsqueciMinhaSenhaViewModel vModel)
{
if (ModelState.IsValid)
{
var conteudo = "este é o conteudo do email";
var nomeRemetente = "esse é o nome do remetente";
if(await EmailService.SendAsync(Language.PasswordRecovery, conteudo, vModel.EmailOuUsername, nomeRemetente))
{
TempData["MensagemRetorno"] = Language.EmailSendedWithSuccess;
return View("login");
}
}
TempData["MensagemRetorno"] = Language.ErrorSendingEmail;
return View("EsqueciMinhaSenha");
}
My Email Service:
public static async Task<bool> SendAsync(string assunto, string conteudo, string destinatario, string nomeDestinatario)
{
// Habilitar o envio de e-mail
var appSetting = ConfigurationManager.AppSettings;
if (appSetting != null && appSetting.Count >= 7 && !string.IsNullOrEmpty(assunto) && !string.IsNullOrEmpty(conteudo) && !string.IsNullOrEmpty(destinatario) && !string.IsNullOrEmpty(nomeDestinatario))
{
int port = 0;
bool useSSl = false;
using (var msg = new MailMessage
{
From = new MailAddress(appSetting["EmailFrom"], appSetting["EmailNameFrom"]),
Body = WebUtility.HtmlEncode(conteudo)
})
{
int.TryParse(appSetting["EmailPort"], out port);
bool.TryParse(appSetting["EmailUseSSL"], out useSSl);
msg.ReplyToList.Add(destinatario);
msg.To.Add(new MailAddress(destinatario, nomeDestinatario));
msg.Subject = assunto;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(msg.Body, null, MediaTypeNames.Text.Plain));
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(msg.Body, null, MediaTypeNames.Text.Html));
using (var smtpClient = new SmtpClient(appSetting["EmailServer"], port))
{
var credentials = new NetworkCredential(appSetting["EmailUserName"], appSetting["EmailPassword"]);
smtpClient.Credentials = credentials;
smtpClient.EnableSsl = useSSl;
await smtpClient.SendMailAsync(msg);
return await Task.FromResult(true);
}
}
}
return await Task.FromResult(false);
}
Stack Trace:
[InvalidOperationException: The asynchronous action method 'esqueciminhasenha' returns a Task, which cannot be executed synchronously.]
System.Web.Mvc.Async.TaskAsyncActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +119
2 parameters) +27
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
System.Web.Mvc.<>c__DisplayClass15.b__12() +55 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +253
1 filters, ActionDescriptor actionDescriptor, IDictionary
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +22 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList2 parameters) +189
2.CallEndDelegate(IAsyncResult asyncResult) +16
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +521
System.Web.Mvc.Controller.ExecuteCore() +95
MusiArtist.MVC.Areas.admin.Controllers.BaseController.ExecuteCore() in F:\Backup\BitBucket\negrini.musiartist\src\MusiArtist.MVC\Areas\admin\Controllers\BaseController.cs:29 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +180 System.Web.Mvc.<>c__DisplayClass19.<BeginExecute>b__13() +18 System.Web.Mvc.Async.AsyncResultWrapper.<.cctor>b__0(IAsyncResult asyncResult, Action action) +15
System.Web.Mvc.Async.WrappedAsyncResult
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9765121 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
When to use Asynchronous Controller. Asynchronous action methods are useful when an action must perform several independent long running operations. Suppose we have three operations which takes 500, 600 and 700 milliseconds. With the synchronous call, total response time would be slightly more than 1800 milliseconds.
There are some massive benefits to using Asynchronous Controllers with MVC. If your application is I/O or network limited, adding an Asynchronous Controller can help your application stay responsive. It's also a really sexy way of handling long running operations without blocking your application.
Asynchronous actions are best when your method is I/O, network-bound, or long-running and parallelizable. Another benefit of an asynchronous action is that it can be more easily canceled by the user than a synchronous request.
I made an override on the "DisableAsyncSupport" method of the Controller and set the getter to false and everything worked perfectly!!!
protected override bool DisableAsyncSupport
{
get { return false; }
}
I believe that by inheriting from controller (I have my own controller, "ControllerBase") the method must behave differently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With