Веб-службы WCF, возвращающие строку ошибки / исключения
У меня есть набор веб-служб WCF, которые, в случае возникновения исключения, будут использовать OutgoingWebResponseContext
вернуть описание ошибки обратно вызывающей стороне.
Моя проблема в том, что иногда, когда что-то идет не так, веб-сервис отображается как сбой с сообщением ERR_CONNECTION_RESET, а не возвращает сообщение об ошибке, и я хотел бы предотвратить это.
Например, вот мой красивый код C#, который запрашивает мой Northwind
базы данных, и возвращает список Customer
имена.
Вернее, так и будет, но я намеренно вставил исключение.
public List<string> GetAllCustomerNames()
{
// Get a list of unique Customer names.
//
try
{
throw new Exception("Oh heck, something went wrong !");
NorthwindDataContext dc = new NorthwindDataContext();
var results = (from cust in dc.Customers select cust.CompanyName).Distinct().OrderBy(s => s).ToList();
return results;
}
catch (Exception ex)
{
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
response.StatusDescription = ex.Message;
return null;
}
}
В моем контроллере AngularJS я могу вызвать этот веб-сервис...
$http.get('http://localhost:15021/Service1.svc/getAllCustomerNames')
.then(function (data) {
// We successfully loaded the list of Customer names.
$scope.ListOfCustomerNames = data.GetAllCustomerNamesResult;
}, function (errorResponse) {
// The WCF Web Service returned an error
var HTTPErrorNumber = errorResponse.status;
var HTTPErrorStatusText = errorResponse.statusText;
alert("An error occurred whilst fetching Customer Names\r\nHTTP status code: " + HTTPErrorNumber + "\r\nError: " + HTTPErrorStatusText);
});
... и если возникает это исключение, я вижу полное сообщение об исключении...
Замечательно.
Для всех читателей, которые хотели бы знать простой, общий способ возврата и отображения исключений из ваших веб-служб WCF, есть ваше решение!
Хорошо, теперь я удалю строку кода моего исключения, и веб-служба снова будет работать нормально. Customer
данные возвращаются в угловой контроллер без каких-либо проблем.
Но... если возникает исключение при соединении с базой данных (например, когда истекает время, у меня неверное имя базы данных в строке подключения и т. Д.), То следующая строка кода вызывает исключение...
NorthwindDataContext dc = new NorthwindDataContext();
... мой catch
код срабатывает (я ставлю точку останова для проверки), и мы устанавливаем StatusDescription в сообщение об исключении.
Но ответ, который отправляется обратно, не содержит ни моего номера статуса HTTP, ни текста.
Мой контроллер Angular просто получает HTTP-код состояния 0 без StatusMessage.
И если я нажму F12 в Chrome, вы увидите, что на самом деле он говорит, что веб-служба не работает, а не возвращает код состояния 403, и сообщения нет.
Итак, мой вопрос прост: есть ли способ предотвратить этот сбой?
Очевидно, гораздо приятнее возвращать описание того, что пошло не так, а не просто "Веб-служба с треском провалилась... но мы не можем сказать вам, почему".
Если бы я мог справиться с этой проблемой, это был бы хороший способ сделать все наши сообщения об ошибках веб-служб WCF дружественными в наших собственных приложениях. Но, конечно, для производственных систем, конечно же, вы не захотите бомбардировать пользователя техническими сообщениями об исключениях.
Обновление, много часов спустя..
Я нашел причину и решение.
Готовы ли вы к этому?
Проблема заключалась в том, что когда DataContext
линия выкинула исключение...
NorthwindDataContext dc = new NorthwindDataContext();
... в сообщении об исключении есть перевод строки.
Cannot open database "Northwind" requested by the login.
The login failed.Login failed for user 'MikesWrongUserName'.This session has been assigned a tracing ID of '1f0513d1-9ce1-47ef-9d44-1f4546eb0b73'. Provide this tracing ID to customer support when you need assistance.
Этот перевод строки был причиной проблемы. Если вы попытаетесь вернуть это в StatusDescription
поле, это заставляет весь веб-сервис сообщаться как "сбой".
Таким образом, решение состоит в том, чтобы просто удалить все переводы строк, прежде чем вы вернете сообщение об исключении.
Итак, вот, наконец, пример того, как использовать try..catch
в ваших веб-службах WCF, поэтому они всегда будут возвращать сообщения об исключениях обратно вызывающей стороне.
public List<string> GetAllCustomerNames()
{
// Get a list of unique Company Names.
//
try
{
NorthwindDataContext dc = new NorthwindDataContext();
var results = (from cust in dc.Customers select cust.CompanyName).Distinct().OrderBy(s => s).ToList();
return results;
}
catch (Exception ex)
{
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
// If a database Exception occurs, it might have a line-feed in it,
// which will cause the web service to completely fail (no Status
// Code or Status Message will get returned.)
response.StatusDescription = ex.Message.Replace("\r\n", "");
return null;
}
}
Спасибо за все ваши предложения!