2015-03-04 2 views
0

Этот HttpHandler не отправляет ответ, если con.Open() выдает исключение, например, если faultyConnectionString имеет недопустимое имя базы данных. Зачем?HttpHandler не отправляет ответ после обнаружения SqlException?

public void ProcessRequest(HttpContext context) 
{ 
    int status = 400; 
    string message = "Test error!"; 
    string faultyConnectionString = "Data Source=LOCALHOST\\SQLEXPRESS;Initial Catalog=XXX;User ID=XXX;Password=XXX"; 
    try 
    { 
     using (SqlConnection con = new SqlConnection(faultyConnectionString)) 
     { 
      //throw new Exception("This works as expected, and is returned to client"); 
      con.Open(); 
     } 
    } 
    catch (Exception ex) 
    { 
     status = 500; 
     message = "Test Exception: " + ex.Message; 
    } 

    context.Response.StatusCode = status; 
    context.Response.StatusDescription = message; 
} 

Вот как я обработки вызова в клиенте:

function GetContacts() { 
    $.ajax({ 
    type: "POST", 
    url: "xxx.ashx", 
    data: "", 
    contentType: "application/x-www-form-urlencoded; charset=utf-8", 
    dataType: "text", // "json", 
    success: function (response, a, b) { 
     alert(response.status + " " + response.statusText); 
    }, 
    error: function (response, a, b) { 
     alert(response.status + " " + response.statusText); 
    } 
    }); 
} 

Если я f12 в FireFox он показывает мне, что нет никакого ответа получено после отправки запроса. В IE это показывает мне «SCRIPT7002: XMLHttpRequest: ошибка сети 0x2ef3, не удалось завершить операцию из-за ошибки 00002ef3». В обоих случаях вызов jquery ajax возвращает status = 0 и statusText = "error".

Если я прокомментирую две строки внутри блока catch, то он работает так, как ожидалось, отправляя код 403 клиенту и игнорируя исключение.

Различные типы исключений не имеют такой же проблемы. Если я создам новый Exception() до con.Open(), то он также работает так, как ожидалось. Чем отличается SqlException?

UPDATE: В первый раз, когда я попал в ProcessRequest, он вызван 5 раз подряд, прежде чем клиент отобразит результат status = 0 (точка останова на первой строке будет удалена 5 раз).

FIDDLER: Если я запустил Fiddler, он (fiddler) перехватит транзакцию и отправит «504 Fiddler - Receive Failure» на мой вызов ajax. Похоже, что первоначальное повторение может быть механизмом повтора, когда активен скрипач, он делает это 13 раз. Fiddler сообщает: «Session #xxx поднял исключение System.Net.Sockets.SocketException Существующее соединение было принудительно закрыто удаленным хостом».

ответ

1

Я считаю, что ваш клиент (браузер) обрабатывает ошибки 404, что вызывает это, и каждый тип браузера обрабатывает ошибку по-разному. Ошибки 404 относятся к «Not Found», поэтому вы можете использовать другой код ошибки, например, ошибку 500. Более подробную информацию о кодах ошибок можно найти здесь: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Пожалуйста, имейте в виду, что передача подробных сообщений об ошибках клиенту может быть проблемой безопасности из-за утечки информации. Возможно, вам лучше отказаться от общей ошибки для клиента и зарегистрировать подробную информацию об ошибках на стороне сервера.

Edit: Тестирование это локально, как вы настраиваете context.Response.StatusDescription содержать ex.Message производит неверный ответ HTTP. Попробуйте только поместить текст, например Внутренняя ошибка сервера. Дополнительные сведения могут быть добавлены в тело ответа с использованием context.Response.Write(bodyText), но, пожалуйста, не забывайте об этом.

+0

Я могу разместить любые коды, которые мне нравятся, проблема в том, что сервер ничего не отправляет клиенту, если у меня есть код внутри блока catch (предположительно комментирование кода вызывает тонкую разницу в скомпилированном коде) , – Etherman

+0

Что произойдет, если вы поместите 403 в блок catch и положите 200 на вершину вместо 403? Вы можете захотеть проверить ответ HTTP, когда блок catch используется, а не используется, чтобы точно видеть, что передается сервером. В дополнение к инструментам F12, Fiddler также полезен для устранения неполадок HTTP. – aoporto

+0

Я пробовал все комбинации. Даже если я поставил 200 в обоих местах. Проблема заключается в том, что после исключения SqlException ответа HTTP нет, поэтому проверить нечего. Если SqlConnection выдает исключение ArgumentException в фиктивной строке подключения, то он работает так, как ожидалось. Но как только con.Open() выдает исключение SqlException (например, несуществующее имя БД), тогда он терпит неудачу. – Etherman