Если вы знаете, что у вас есть собственные исключения приложения, которые не раскрывают конфиденциальную информацию, вы можете обработать эти конкретные исключения и сопоставить свойство сообщения. Для других исключений вы можете пропустить отображение сообщения. Кроме того, вы можете указать сообщение исключения в самом договоре о сбое:
<add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="ThrowNewException" name="Exception">
<exceptionHandlers>
<add exceptionMessage="Oops! A System Error Occurred in the Service Layer." faultContractType="MyTypes.Exceptions.ServiceFault, MyTypes.Exceptions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Default Fault Contract Handler">
</add>
exceptionMessage
будет заполнено в свойстве Message FaultException. Если вы не отобразите детали, этого может быть достаточно для вас.
Если вы хотите заполнить значения в классе ошибок, вы можете сделать это в два этапа:
- Создайте обработчик (и) для обработки интересующего вас исключения и обработайте сообщение.
- Создание обработчика для создания FaultContract
Использование Обработка исключений WCF Гая Бурштейна с обработкой исключений Интеграция блока приложения Пример этого будет установка MessageText ServiceFault (остальное на этом примере).
Итак, ваш сервис будет выглядеть так:
public int CreateOrder(string currency, double amount)
{
try
{
throw new InvalidOperationException("Cannot call this operation!");
}
catch (Exception e)
{
// This sanitizes the message and throws a new Exception
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.
HandleException(e, "SanitizeAndThrow");
}
return 0;
}
Затем в конфигурации вы создадите обработчик SanitizeAndThrow для очистки сообщения:
<add name="SanitizeAndThrow">
<exceptionTypes>
<add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="ThrowNewException" name="Exception">
<exceptionHandlers>
<add exceptionMessage="This is a sanitized message."
replaceExceptionType="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
name="Replace Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
Затем вы можете использовать экранирование исключений для создания исключения FaultException:
<add name="WCF Exception Shielding">
<exceptionTypes>
<add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException" name="Exception">
<exceptionHandlers>
<add exceptionMessage="Oops!"
type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF"
name="DefaultFaultContract Handler"
faultContractType="Bursteg.Samples.WCFIntegration.ServiceContracts.ServiceFault, Bursteg.Samples.WCFIntegration.ServiceContracts">
<mappings>
<add name="Id" source="{Guid}"/>
<add name="MessageText" source="{Message}"/>
</mappings>
</add>
</exceptionHandlers>
</add>
Некоторые примечания об этом примере:
Если вы не очистите исключение, тогда возможно утечка сообщения. Этого можно избежать, если обработчик «SanitizeAndThrow» генерирует собственное исключение, а политика экранирования обрабатывает ваши пользовательские типы и отображает сообщение, но для любого другого типа не выполняет сопоставление.
Этот код не готов к работе и не соответствует рекомендациям. Это всего лишь пример и отправная точка. например Вы обычно не хотите поймать общее Exception
, сервисный код не имеет логики NotifyRethrow и т. д.
При необходимости вы можете создать пользовательский обработчик контракта ошибок, чтобы обрабатывать более сложные сценарии.
Возможно, существует более простой способ очистки Detail
исключения ошибки (например, обработчики цепочек в экранировании исключения)?