У меня есть набор веб-сервисов SOAP, которые обертывают исключения, используя IErrorHandler, в частности:
public sealed class ErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
// don't wrap existing fault exceptions
if ((error is FaultException)) return;
// our basic service fault
var businessFault = new BusinessFault { FaultMessage = error.Message, FaultReference = "Internal" };
// Resource based faultReason
var faultReason = new FaultReason(Properties.Resources.BusinessFaultReason);
var faultcode = FaultCodeFactory.CreateVersionAwareSenderFaultCode(InternalFaultCodes.BusinessFailure.ToString(), Service.Namespace);
var faultException = new FaultException<BusinessFault>(
businessFault,
faultReason,
faultcode);
// Create message fault
var messageFault = faultException.CreateMessageFault();
// Create message using Message Factory method
fault = Message.CreateMessage(version, messageFault, faultException.Action);
}
}
Теперь я добавил дополнительные конечные точки для Json и Pox, которые работают нормально, если не возникает исключение. В случае конечной точки Json исключение FaultException возвращается как XML.
Я знаю из других сообщений SO, что в случае REST я бы лучше выбрал исключение WebHttpException:
throw new WebFaultException<BusinessFault>(detail, HttpStatusCode.BadRequest);
Или переопределение свойств ответного сообщения в ProvideFault, таким образом:
var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);
var rmp = new HttpResponseMessageProperty
{
StatusCode = System.Net.HttpStatusCode.BadRequest,
StatusDescription = "See fault object for more information."
};
fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);
Однако MSDN имеет несколько интересных замечаний о WebHttpException, а именно:
При использовании конечной точки REST WCF (WebHttpBinding и WebHttpBehavior или WebScriptEnablingBehavior) установлен код состояния HTTP в ответе соответственно. Однако WebFaultException может использоваться с не-REST endpoints и ведет себя как регулярное исключение FaultException.
При использовании конечной точки REST WCF формат ответа сериализованного ошибка определяется так же, как и ответ на отказ. Для большего информация о форматировании WCF REST, см. форматирование WCF REST.
Поэтому мне было бы необходимо преобразовать мой текущий метод ProvideFault, чтобы предоставить новое исключение WebHttpException (обертывание любых существующих исключений или исключений FaultExceptions), а затем SOAP все равно будет работать.
Кто-нибудь хотел бы нанести удар по тому, что будет выглядеть (.Net4.0 btw)? Я хочу, чтобы один обработчик ошибок правил для всех!