Веб-службы 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;
}
}
Спасибо за все ваши предложения!