Возврат значимых исключений из проекта WCF - PullRequest
4 голосов
/ 30 марта 2010

Я довольно новичок в WCF в целом. У меня мало опыта в использовании довольно простых служб .SVC в веб-приложениях ASP.NET.

Я впервые попробовал поэкспериментировать с использованием проекта WCF и натолкнулся на крупный ограничитель шоу.

Как я уверен, большинству известно, по какой-то странной причине, в веб-приложении, в котором режим customErrors установлен на Вкл

<customErrors mode = “On” />

сервисы (как .ASMX, так и .SVC) не будут возвращать детали исключения клиенту. Вместо этого очищается исключение и трассировка стека, и в сообщении всегда указывается «Произошла ошибка при обработке запроса», что совершенно не помогает.

Когда службы размещаются непосредственно в самом веб-приложении, обойти это ограничение легко, поместив службы в отдельную папку и установив для CustomErrors значение «Выкл.» Для этой папки.

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

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

РЕДАКТИРОВАТЬ : Я, вероятно, должен указать здесь, что причина, по которой я хотел бы возвращать исключения, заключается в том, что я часто вызываю эти сервисы со стороны клиента через Ajax (jQuery) и хотел бы отформатируйте ответное сообщение по-разному, если это «нормальный» возврат (например, используйте зеленый текст), а затем используйте красный текст, если это ошибка. Я обрабатываю форматирование сообщения в обработчике ошибок объекта $ .ajax, который, очевидно, будет работать только при сбое службы.

Я также должен отметить, что все работает нормально с customErrors Off:

<customErrors mode = “Off” />

Итак, я думаю, что, может быть, есть какое-то свойство конфигурации, которое можно настроить, чтобы среда ASP.NET не убивала мое исключение при использовании customErrors.

Здесь - некоторая связанная информация, которую я нашел по этому вопросу.

Ответы [ 3 ]

3 голосов
/ 30 марта 2010

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

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

Пример:

[DataContract(Namespace = "urn:// or http://....")]
public class ClientNeedsToKnowFault
{
    [DataMember]
    public List<Error> Errors
    {
        get { return _errors; }
        set { _errors = value; }
    }

     ....
    public ClientNeedsToKnowFault() { }

    public ClientNeedsToKnowFault(string message)
    {
        Message = message;
        Errors = new List<Error>() { new Error(message) };
    }



    ...
    //Helper method to throw
     public static void ThrowFault(string message, List<Error> errorList)
    {
        throw new FaultException<ClientNeedsToKnowFault>(new ClientNeedsToKnowFault(message, errorList));
    }

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

[FaultContract(typeof(ClientNeedsToKnowFault))]
 void MyServiceMethod();

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

Я скажу, что основным недостатком этого подхода является обнаружение сбоя на стороне клиента. Но если информация достаточно важна, чтобы вернуть ошибку, вы, вероятно, захотите эту сложность.

1 голос
/ 30 марта 2010

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

1 голос
/ 30 марта 2010

Реальный ответ здесь заключается в том, что вы, вероятно, всегда должны избегать пузырящихся реальных исключений для вызывающей стороны. Шаблон «ServiceResponse» здесь полезен. Идея состоит в том, что вы вернете класс «ServiceResponse», который содержит любые значения ответа, необходимые для вашей службы, но также имеет своего рода флаг «IsError» в дополнение к свойству, которое позволяет возвращать объект Exception.

Затем служба может просто обработать все ошибки и вернуть эту информацию:

public ServiceResponse MyService()
{
  try { 
    // ... do work here
    return new ServiceResponse { WhateverReturnValue = true };
  } catch(Exception e) {
    return new ServiceResponse { IsError = true, Error = e };
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...