審查,並試圖許多周圍的錯誤消息的建議後:MVC,ASP.NET身份,EmailService和異步調用W/Angularjs
「異步模塊或處理程序完成,而異步 操作仍待定「。
,我發現自己在即使調用MVC的AccountController實際執行的控制器方法所需的代碼(電子郵件被髮送到與正確的內容在正確的地方)和一個try/catch情況會不會'捕捉'錯誤,發起呼叫的AngularJS工廠將收到服務器錯誤「頁面」。
工廠:(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;
}
}
身份存儲庫/ 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 = "[email protected]";
private const string USER_NAME = "noreply";
private const string PASSWORD = "[email protected]"; //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 = "[email protected]";
#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;
}
}
(注:原控制方法只是「公共異步任務InitiateResetPassword,我添加了返回類型爲試圖捕獲的錯誤服務器。在運行時,返回0;沒有命中(斷點)的捕獲不會被擊中和在客戶端「)
目前,我只是過濾預期的錯誤消息,並告訴JavaScript將其視爲成功。 「實際工作」 ......但它不是「理想」。
如何防止在服務器上的錯誤? 或交替, 如何捕獲錯誤的服務器上?
您是否需要等待EmailService中的Task.FromResult?問題不在角度,但與C#代碼..這就是你必須看看 – sirrocco
@sirrocco感謝您的問題;我已經意識到這個問題居住在C#代碼中,我提供了角度位以顯示調用來自何處以及遇到問題的位置。 IIdentityMessageService強制「SendAsync」是一個異步任務......並且我從一個等待狀態改變爲等待Task.FromResult ......這顯然不僅是「不需要的」,而是問題的根源。請將您的評論轉換爲答案,我會接受它。 –
...另外:關於爲什麼這個錯誤不會被困在服務器上的想法? –