Я пытаюсь устранить проблему с исключениями, которые не проходят до моего вызова ajax должным образом.Асинхронный метод в контроллере называется несколько раз, когда исключение исключено
Мой метод асинхронного контроллера называется несколько раз, где я отправляю только один запрос ajax. Ответ должен быть отправлен, но, глядя на вкладку сети в панели отладки Firefox, я не вижу ответа; функция обработчика ошибок ajax также имеет readyState = 0. Это происходит только тогда, когда исключение выбрасывается внутри метода асинхронного контроллера.
Есть три/четыре части этой проблемы:
- Мой Javascript
- Мой метод управления асинхронной
- Асинхронный частный метод контроллера вызывается второй
- Методы JsonError и JsonSuccess форматирования ответ
Ajax call:
function test() {
var data = {
campagneId: 15,
tiersNum: 2721
};
console.debug("Starting Ajax !");
$.ajax({
url: "/CampagnesMailing/SendMail",
data: data,
method: "POST",
success: function (response) {
console.debug("Sent mail successfully!");
},
error: function (xhr, ajaxOpt, thrownError) {
console.error("Error!");
console.error(xhr); //xhr.readyState is 0
console.error(ajaxOpt);
console.error(thrownError); //this is empty
},
complete: function() {
console.debug("Finished ajax call!");
}
});
}
$("#goButton").on("click", test);
Асинхронный метод контроллера вызывается AJAX:
[HttpPost]
public async Task<ActionResult> SendMail(int campagneId, int tiersNum)
{
try
{
MailMessage mail = await GetMailFor(campagneId, tiersNum); //I tried adding .ConfigureAwait(false) with no change
return JsonSuccess();
}
catch (Exception e)
{
return JsonError(e);
}
}
Асинхронный метод GetMailFor:
private async Task<MailMessage> GetMailFor(int campagneId, int tiersNum)
{
try
{
MailMessage mail = new MailMessage();
mail.To.Add(new MailAddress("")); // This throws an ArgumentException
return mail;
}
catch (Exception e)
{
throw;
}
}
JsonError/JsonSuccess:
protected JsonResult JsonSuccess()
{
Response.StatusCode = (int) System.Net.HttpStatusCode.OK;
Response.StatusDescription = "SUCCESS";
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
protected JsonResult JsonError(Exception e)
{
Response.StatusCode = (int) System.Net.HttpStatusCode.InternalServerError;
Response.StatusDescription = e.Message;
//HttpContext.ApplicationInstance.CompleteRequest();
return Json(new {e.Message}, JsonRequestBehavior.AllowGet);
}
Когда я поставил точку останова на первой строка SendMail (одна с MailMessage mail = await GetMailFor(campagneId, tiersNum);
) a nd точка останова в catch, я вижу, что метод вызывается 7 раз и каждый раз попадает в catch, в основном с разными значениями ManagedThreadId
в System.Threading.Thread.CurrentThread
.
Как ни странно, если я заменю вызов mail.To.Add()
на throw new ArgumentException("Boom");
, процесс идет хорошо, и только один вызов поймал в моих контрольных точках.
Я посмотрел this issue, но добавив HttpContext.ApplicationInstance.CompleteRequest();
до return Json(new {e.Message}, JsonRequestBehavior.AllowGet);
ничего не изменил.
Я вижу только 1 запрос POST на вкладке «Сеть» от firefox. Это никогда не получает никакого ответа. Обратите внимание, что этих фрагментов достаточно, чтобы вызвать проблему, но я использую больше кода в реальном приложении (нет необходимости предупреждать меня об асинхронном методе, не ожидающем).
Что происходит? Почему SendMail называется 7 раз? Почему только, когда new MailAddress()
бросает, а не когда я бросаю вручную? Как я могу отлаживать такое поведение?
EDIT: Удаление попытки/улова изнутри метода GetMailFor
не дает никаких изменений.
EDIT2: Удаление любого упоминания о async
, Task<T>
или await
также не дает никаких изменений, так что это не имеет ничего общего с async
проблемы. Я сейчас потерялся, потому что не знаю, как отлаживать это ...
EDIT3: Я никогда не войти в функцию Application_Error
, но я вхожу Application_BeginRequest
каждый раз перед входом SendMail
и Application_EndRequest
каждый раз после возвращения JsonError
Является ли это контроллер MVC или WebAPI? –
MVC, извините, я забыл пометить его. – Eregrith
Я не понимаю, почему все это «асинк»? – DavidG