WCF: ошибка SOAP или обычные исключения в классе DataContract - PullRequest
1 голос
/ 29 марта 2011

Основным параметром OperationContract моей службы является класс Preapproval.В классе Preapproval есть несколько общедоступных методов получения / установки для атрибутов DataMember.У меня есть код, который проверяет входные данные для установщиков, так что я бы выбрасывал ArgumentException, если, скажем, параметр пустой или выходит за пределы допустимых границ домена.

Если входные данные недействительны, я обычнобросил бы ArgumentException здесь.Так как это ситуация WCF, я должен бросить здесь предопределенное исключение FaultException, а не ArgumentException?Я понимаю, что в других местах я могу перехватывать общие исключения и перебрасывать их как FaultExceptions, но это действие будет происходить выше по стеку, в некоторых работах, выполняемых автоматически сантехникой WCF.

Например, когда вызывающая сторона вызывает мойВ этом случае сериализатор будет десериализовать свой SOAP, попытаться вызвать сеттеры для моего объекта и испытать выброс ArgumentException задолго до того, как моя операция будет фактически запущена.Таким образом, является ли хорошей практикой проектирования в классах DataContract просто выбрасывать FaultExceptions сразу?Я действительно не хочу связывать пользовательский обработчик с диспетчером каналов.

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

Спасибо!

Ответы [ 2 ]

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

Я бы исключил FaultExceptions из вашего класса DataContract - вы можете использовать эти классы вне контекста WCF.

Один из подходов, который предотвратит проникновение определенного кода WCF в ваши DataContracts (помимо атрибутов), заключается в том, чтобы класс DataContract выбрасывал исключения, а на уровне службы использовал Защита исключений WCF Enterprise Library для сопоставления этих исключений по вине контрактов.

В основном Enterprise Library реализует IErrorHandler и преобразует исключения в FaultExceptions. Я думаю, что обработчик - единственный способ достичь того, чего вы хотите (поскольку исключения не добавляются в ваш сервис). Хорошей новостью является то, что вам действительно не нужно много делать, чтобы это заработало.

Просто добавьте атрибут к вашему сервису:

[ServiceContract]
[ExceptionShielding]
public interface IApproval
{
    [OperationContract]
    [FaultContract(typeof(ApplicationServiceFault))]
    [FaultContract(typeof(SystemServiceFault))]
    void PreApprove(Preapproval preapproval);
}

, а затем добавьте некоторую конфигурацию (конфигурация опущена для экономии места) для сопоставления исключений с FaultContract. Обратите внимание, что ваши операции все равно должны будут объявить FaultContracts.

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

Ваш класс PreApproval не должен знать, что он используется в веб-сервисе. Пусть он сгенерирует любое исключение, которое он сгенерировал бы, если бы он вызывался из любого другого типа приложения.

«Верхний уровень» вашего сервиса должен перехватывать исключения и переводить их в соответствующие FaultException.

...