Службы WCF REST-общая обработка исключений
у меня много устаревшего кода, который теперь является бэкэндом для службы WCF REST-раньше это был обычный бэкэнд службы WCF, если это имеет значение. Я хочу реализовать механизм, который поймает любое исключение в любом методе и проанализирует его. Если это окажется известной ошибкой, она будет обработана и превращена в дружественную ошибку.
Я знаю, что могу бросить FaultException
или WebProtocolException
вместо "обычных" исключений, но есть много мест, где создаются исключения по всему коду, и искать их все довольно болезненный вариант.
Я попытался добавить расширение поведения конечной точки, которое создает новое поведение, которое переопределяет standard WebHttpBehavior.AddServerErrorHandlers
метод и добавляет мои обработчики ошибок (IErrorHandler
реализации) в коллекцию обработчиков ошибок диспетчера конечных точек. Внутри обработчиков ошибок я анализирую исключение и создаю (или не создаю) желаемую ошибку на основе этого исключения.
Я ожидал, что этот механизм вернет custom данные для любого известного исключения, но я ошибался. Старый добрый Microsoft реализовал замечательный неизбежный WebHttpBehavior2
, что, безусловно, добавляет внутренний Microsoft.ServiceModel.Web.WebErrorHandler
в конец коллекции обработчиков ошибок диспетчера конечных точек. Этот обработчик игнорирует все ранее выполненные обработчики и распознает только небольшой набор исключений, в то время как большинство интерпретируется как "внутренняя ошибка сервера", и ничего больше.
вопрос в том, нахожусь ли я на правильном пути, и есть способ отключить этот обработчик в механизме WCF REST или вводит его с новым исключением (например, когда любое исключение поймано, оно сначала обрабатывается моими обработчиками, и если они бросают/возвращают, например, FaultException, то это новое исключение предоставляется Microsoft.ServiceModel.Web.WebErrorHandler
вместо оригинального). Если все мои эксперименты с IErrorHandler
и расширения поведения бесполезны, что такое альтернатива? Опять же, я действительно не хочу изменять логику метания исключений, я хочу, чтобы одно место ловило исключения и обрабатывать их.
Спасибо большое!
2 ответов
когда вы изменяете службы WCF SOAP на REST, изменяется весь настрой отчетов об ошибках и обработки.
в SOAP ошибки являются частью вашего контракта. В REST они просто становятся кодами, которые вы выводите в коде ответа HTTP и описании.
вот фрагмент catch:
catch (Exception e)
{
Trace.WriteLine(e.ToString());
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.UnsupportedMediaType; // or anything you want
response.StatusDescription = e.Message;
return null; // I was returning a class
}
поэтому я бы предложил вам создать вспомогательный код, который создает соответствующие коды ошибок для вас и помещает в ответ.
Это то, что я делал в прошлом
public class MyServerBehavior : IServiceBehavior {
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters) {
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase) {
foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers) {
chDisp.IncludeExceptionDetailInFaults = true;
if (chDisp.ErrorHandlers.Count > 0) {
// Remove the System.ServiceModel.Web errorHandler
chDisp.ErrorHandlers.Remove(chDisp.ErrorHandlers[0]);
}
// Add new custom error handler
chDisp.ErrorHandlers.Add(new MyErrorHandler());
}
}
public void Validate(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase) {
}
}
MyErrorHandler был моим классом, который реализовал IErrorHandler.