2010-03-30 3 views
4

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

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

Я уверен, что большинство из них знают, по какой-то странной причине, в веб-приложении, в котором режим CustomErrors установлен в On

<customErrors mode = “On” /> 

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

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

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

Вкратце: мне нужно, чтобы мои службы проекта WCF пузыряли РЕАЛЬНЫЕ исключения для клиента - или, по крайней мере, оригинальное сообщение об исключении вместо «Произошла ошибка обработки запроса».

EDIT: Я, вероятно, следует подчеркнуть, что причина, я хотел бы вернуться исключения в том, что я часто называть эти услуги со стороны клиента с помощью Ajax (JQuery), и хотел бы форматировать возвращение иначе, если это «нормальный» возврат (например, используйте зеленый текст), а затем используйте красный текст, если это ошибка. Я обрабатываю форматирование сообщения в обработчике ошибок объекта $ .ajax, который, очевидно, будет работать только при сбое службы.

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

<customErrors mode = “Off” /> 

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

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

ответ

3

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

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

Пример:

[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 немного беспорядочен.

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

+0

Я действительно пробовал это, но все же, когда , сообщение об исключении (фактически, весь объект исключения и трассировка стека) подавляется. С все работает нормально. Это заставляет меня поверить, что каким-то образом я должен каким-то образом скрывать исключение за время выполнения ASP.NET. ;) – MissingLinq

+0

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

+0

Я уловил исключение. Но, как я уже сказал, все, что я получаю, - это сообщение «Ошибка в обработке запроса». Не уверен, что вы подразумеваете под «регенерированием прокси» - возможно, это то, что мне не хватает ... – MissingLinq

1

Настоящий ответ заключается в том, что вы, вероятно, всегда избегаете пузырьков реальных исключений для вызывающего. Шаблон «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 }; 
    } 
} 
+0

Я видел этот шаблон, используемый alot, мы обобщаем его немного больше и имеем объект Value и список ошибок, а затем выводим HasError на основе того, что список не является нулевым и имеет что-то в нем. – Nix

+0

Да, в нем много вариаций, но корневая концепция заключается в том, что вы должны возвращать неизменное значение независимо от того, была ли внутренняя ошибка. Клиент должен только обрабатывать такие вещи, как конечная точка, не найденная (т.е. проблема с конфигурацией на их конце) –

+0

Это похоже на действительный подход. Единственная проблема заключается в том, что, поскольку касается клиента, служба всегда будет возвращать «хороший» ответ, что затрудняет форматирование возвращаемого сообщения по-разному для условий ошибки. (См. Мой EDIT в исходном посте) – MissingLinq

1

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

+2

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

+0

Хорошая точка ... начало редактирования, чтобы удалить ссылку на свойство IncludeExceptionDetailInFaults;) – Kwal

+0

это гораздо лучшая рекомендация, что ваш первый был! –

Смежные вопросы