WCF REST Services - общая обработка исключений - PullRequest
9 голосов
/ 16 декабря 2010

У меня много устаревшего кода, который теперь является бэкэндом для службы REST WCF - раньше это был обычный бэкэнд службы WCF, если это имело значение.Я хочу реализовать механизм, который бы ловил любое исключение в любом методе и анализировал его.Если это окажется известной ошибкой, она будет обработана и превращена в дружескую ошибку.

Я знаю, что могу выдать FaultException или WebProtocolException вместо «обычных» исключений, ноЕсть много мест, где исключения генерируются по всему коду, и поиск их всех является довольно болезненным вариантом.

Я попытался добавить расширение поведения конечной точки, которое создает новое поведение, которое переопределяет стандарт WebHttpBehavior.AddServerErrorHandlers метод и добавляет мои обработчики ошибок (IErrorHandler реализации) в коллекцию обработчиков ошибок диспетчера конечных точек.Внутри обработчиков ошибок я анализирую исключение и создаю (или не создаю) искомую ошибку, основываясь на этом исключении.

Я ожидал, что этот механизм будет возвращать пользовательские данные для любого известного исключения, но я ошибся.Старый добрый Microsoft реализовал замечательный неизбежный WebHttpBehavior2, который безоговорочно добавляет внутренний Microsoft.ServiceModel.Web.WebErrorHandler в конец коллекции обработчиков ошибок диспетчера конечных точек.Этот обработчик игнорирует все ранее выполненные обработчики и распознает только небольшой набор исключений, в то время как большинство интерпретируется как «Внутренняя ошибка сервера», и ничего более.

Вопрос в том, нахожусь ли я на правильном пути и есть лиспособ отключить этот обработчик в механизме WCF REST или ввести его с новым исключением (например, когда любое исключение перехватывается, оно сначала обрабатывается моими обработчиками, и если они выдают / возвращают, например, FaultException, то это новоеисключение предоставляется Microsoft.ServiceModel.Web.WebErrorHandler вместо исходного).Если все мои эксперименты с IErrorHandler и расширениями поведения бесполезны, какова альтернатива?Опять же, я действительно не хочу изменять логику выдачи исключений, я хочу, чтобы одно место ловило исключения и обрабатывало их.

Большое спасибо!

Ответы [ 2 ]

8 голосов
/ 16 декабря 2010

Когда вы изменяете службы WCF SOAP на REST, весь образ мыслей об ошибках и обработке изменений.

В SOAP сбои являются частью вашего контракта.В REST они просто становятся кодами, которые вы выводите в коде и описании ответа HTTP.

Вот фрагмент кода:

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
}

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

2 голосов
/ 16 декабря 2010

Это то, что я делал в прошлом

    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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...