MVCMailer SendAsync() не работает с Amazon SES
Если я использую Send() с MVCMailer, мой SES работает нормально, но SendAsync() показывает сообщение об ошибке ниже, кто-нибудь знает обойти это? Спасибо!
System.Net.Mail.SmtpException: Failure sending mail. ---> System.InvalidOperationException: An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>.
at System.Web.AspNetSynchronizationContext.OperationStarted()
at System.ComponentModel.AsyncOperation.CreateOperation(Object userSuppliedState, SynchronizationContext syncContext)
at System.Net.Mail.SmtpClient.SendAsync(MailMessage message, Object userToken)
--- End of inner exception stack trace ---
at System.Net.Mail.SmtpClient.SendAsync(MailMessage message, Object userToken)
at Mvc.Mailer.SmtpClientWrapper.SendAsync(MailMessage mailMessage, Object userState)
at Mvc.Mailer.MailMessageExtensions.SendAsync(MailMessage message, Object userState, ISmtpClient smtpClient)
at MVCWebsite.Helpers.AccountHelper.RegisterNewUser(BaseDBContext db, AccountViewModelForReg VM, Boolean isCaptchaValid, Boolean modelValidity) in c:\Users\William-Business\Desktop\TWB\TWB Central\Projects\AwesomeSauce\AwesomeSauce\Helpers\AccountHelper.cs:line 316
at MVCWebsite.Controllers.AccountController.Register(AccountViewModelForReg VM, Boolean captchaValid) in c:\Users\William-Business\Desktop\TWB\TWB Central\Projects\AwesomeSauce\AwesomeSauce\Controllers\AccountController.cs:line 308
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<>c__DisplayClass2a.<BeginInvokeAction>b__20()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult)
1 ответ
Решение
Эта ошибка по замыслу. Вы можете отключить это глобально:
<appSettings>
<add key="aspnet:AllowAsyncDuringSyncStages" value="false" />
</appSettings>
ссылка http://msdn.microsoft.com/en-us/library/hh975440.aspx
Что еще нужно рассмотреть, это использовать Task для выполнения асинхронной синхронизации в фоновом режиме, отделив ее от планировщика, который использует ASP.Net. Используя этот метод, вам не нужно менять appSetting.
using Mvc.Mailer;
...
public ActionResult SendWelcomeMessage()
{
Task.Factory.StartNew(() => UserMailer.Welcome().SendAsync());
return RedirectToAction("Index");
}
редактировать
Включение AllowAsyncDuringSyncStages или использование параллельной библиотеки задач имеют потенциальные недостатки. Использование AsyncController не имеет ни одного недостатка. Спасибо @StephenCleary за оспаривание моего ответа.
public class HomeController : AsyncController
{
public void SendMessageAsync()
{
var client = new SmtpClientWrapper();
client.SendCompleted += (sender, args) =>
AsyncManager.OutstandingOperations.Decrement();
AsyncManager.OutstandingOperations.Increment();
new UserMailer().Welcome().SendAsync("", client);
}
public ActionResult SendMessageCompleted()
{
return View();
}
}