在审核并尝试围绕错误消息的许多建议之后:
“异步模块或处理程序在异步时完成 手术还在等待。“
我发现自己处于这样的情况,即使对MVC accountController的调用实际上执行了所需的代码(电子邮件被发送到正确的地方并且具有正确的内容)并且控制器方法中的Try / Catch也不会“捕获” '错误,正在启动呼叫的AngularJS工厂将收到服务器错误“page”。
工厂:(AngularJS)
InitiateResetRequest: function (email) {
var deferredObject = $q.defer();
$http.post(
'/Account/InitiateResetPassword', { email: email }
)
.success(function (data) {
deferredObject.resolve(data);
})
.error(function (data) {
//This is a stop-gap solution that needs to be fixed..!
if (data.indexOf("An asynchronous module or handler completed while an asynchronous operation was still pending.") > 0) {
deferredObject.resolve(true);
} else {
deferredObject.resolve(false);
}
});
return deferredObject.promise;
}
MVC控制器(C#):
[HttpPost]
[AllowAnonymous]
public async Task<int> InitiateResetPassword(string email)
{
try
{
_identityRepository = new IdentityRepository(UserManager);
string callbackUrl = Request.Url.AbsoluteUri.Replace(Request.Url.AbsolutePath, "/account/reset?id=");
await _identityRepository.InitiatePasswordReset(email, callbackUrl);
return 0;
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
return 1;
}
}
Identity Repository / InitiatePasswordReset:
public async Task InitiatePasswordReset(string email, string callbackUrl)
{
try
{
var u = await _applicationUserManager.FindByEmailAsync(email);
string passwordResetToken = await GetResetToken(u);
callbackUrl = callbackUrl + HttpUtility.UrlEncode(passwordResetToken);
await _applicationUserManager.SendEmailAsync(u.Id, RESET_SUBJECT, string.Format(RESET_BODY, u.FirstName, u.LastName, callbackUrl));
}
catch(Exception ex)
{ //another vain attempt to catch the exception...
Console.WriteLine(ex.ToString());
throw ex;
}
}
将EmailService注入ASP.NET标识“ApplicationUserManager”
public class EmailService : IIdentityMessageService
{
XYZMailer xyzMailer;
public EmailService()
{
xyzMailer = XYZMailer.getCMRMailer();
}
public async Task SendAsync(IdentityMessage message)
{
//original code as posted:
//await Task.FromResult(xyzMailer.SendMailAsync(message));
//solution from @sirrocco-
await xyzMailer.SendMailAsync(message);
}
}
最后...... XYZMailer类
class XYZMailer
{
#region"Constants"
private const string SMTP_SERVER = "XYZEXCHANGE.XYZ.local";
private const string NO_REPLY = "noReply@XYZCorp.com";
private const string USER_NAME = "noreply";
private const string PASSWORD = "theMagicP@55word"; //NO, that is not really the password :)
private const int SMTP_PORT = 587;
private const SmtpDeliveryMethod SMTP_DELIVERY_METHOD = SmtpDeliveryMethod.Network;
#endregion//Constants
internal XYZMailer()
{
//default c'tor
}
private static XYZMailer _XYZMailer = null;
public static XYZMailer getXYZMailer()
{
if (_XYZMailer == null)
{
_XYZMailer = new XYZMailer();
}
return _XYZMailer;
}
public async Task<int> SendMailAsync(IdentityMessage message)
{
#if DEBUG
message.Body += "<br/><br/>DEBUG Send To: " + message.Destination;
message.Destination = "me@XYZCorp.com";
#endif
// Create the message:
var mail =
new MailMessage(NO_REPLY, message.Destination)
{
Subject = message.Subject,
Body = message.Body,
IsBodyHtml = true
};
// Configure the client:
using (SmtpClient client = new SmtpClient(SMTP_SERVER, SMTP_PORT)
{
DeliveryMethod = SMTP_DELIVERY_METHOD,
UseDefaultCredentials = false,
Credentials = new System.Net.NetworkCredential(USER_NAME, PASSWORD),
EnableSsl = true
})
{
// Send:
await client.SendMailAsync(mail);
}
return 0;
}
}
(注意:最初控制器方法只是“public async Task InitiateResetPassword,我添加了返回类型,试图在服务器上捕获错误。在运行时,返回0;确实命中(断点)捕获没有被击中并在客户端“)
目前我只是过滤了预期的错误消息并告诉javascript将其视为成功。这种解决方案具有“实际工作”的好处......但它并不“理想”。
如何防止服务器上的错误? 或者, 如何在服务器上捕获错误?
答案 0 :(得分:1)
您需要从await Task.FromResult
中删除EmailService
,因为这样可以使代码同步执行而不是异步。
至于为什么异常仍然在try / catch之外被提出并冒出来 - 我怀疑Task.FromResult
也是罪魁祸首 - 如果你现在在SendAsync
中引发异常(只是为了测试它你应该抓住控制器。