Обработка ошибок WCF
В Как я могу получить исходное исключение (произошло на сервере) на стороне клиента?
Я работаю с собственной службой WCF и C# 4 и пытаюсь настроить правильную обработку исключений.
У меня есть клиент, который выглядит так
private ServiceResponse PerformRemoteAction(ServiceRequest request, ProcessOperations operation)
{
...
try
{
//remote call
switch (operation)
{
...
case ProcessOperations.VerifyAction: { response = client.VerifyAction(request); break; }
default: throw new NotImplementedException();
}
}
catch (Exception ex)
{
AppManager.LogException(ex);
}
return response;
}
И внедрение сервиса
public override ServiceResponse VerifyAction(ServiceRequest request)
{
RegisterRequest(request);
try
{
var chain = new VerificationChain();
Responce = chain.Run(request);
}
catch (Exception ex)
{
throw new FaultException<WcfException>(ExceptionFactory.Create(ex),
new FaultReason(ex.Message));
}
SetSuccessfulResponce();
return Responce;
}
Сервис web.config имеет
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Это мое оригинальное исключение
И это то, что я получаю на клиенте
При необходимости я могу опубликовать полную информацию на стороне клиента, однако исключение на клиенте не имеет никакой ссылки на исходную.
Обновить
Это мой интерфейс с определенным FaultContractAttribute
[ServiceContract]
public interface IServiceOperation : IOperation
{
...
[OperationContract(Action = "http://tempuri.org/ITestRunnerService/VerifyAction", ReplyAction = "http://tempuri.org/ITestRunnerService/VerifyAction")]
[FaultContractAttribute(typeof(WcfException), Action = "http://tempuri.org/ITestRunnerService/ExecuteRequestWcfExceptionFault", Name = "WcfException", Namespace = "http://schemas.datacontract.org/2004/07/TH.Core.Exceptions")]
ServiceResponse VerifyAction(ServiceRequest request);
}
И это мой класс WcfException
[DataContract]
public class WcfException : Exception
{
[DataMember]
public string Title { get; set; }
[DataMember]
public new string Message { get; set; }
[DataMember]
public new string InnerException { get; set; }
[DataMember]
public new string StackTrace { get; set; }
}
4 ответа
Спасибо за все ваши ответы. Моя проблема была в интерфейсе службы, а именно в свойстве Action объекта FaultContractAttribute, оно указывало на неверный URL.
[ServiceContract]
public interface IServiceOperation : IOperation
{
...
[OperationContract(Action = "http://tempuri.org/IServiceOperation/VerifyAction", ReplyAction = "http://tempuri.org/IServiceOperation/VerifyAction")]
[FaultContractAttribute(typeof(WcfException), Action = "http://tempuri.org/IServiceOperation/ExecuteRequestWcfExceptionFault", Name = "WcfException", Namespace = "http://schemas.datacontract.org/2004/07/TH.Core.Exceptions")]
ServiceResponse VerifyAction(ServiceRequest request);
}
Я решил это, удалив все остальные свойства (определяется автоматически) и оставил только тип WcfFault
[ServiceContract]
public interface IServiceOperation : IOperation
{
...
[OperationContract(Action = "http://tempuri.org/IServiceOperation/VerifyAction", ReplyAction = "http://tempuri.org/IServiceOperation/VerifyAction")]
[FaultContractAttribute(typeof(WcfException))]
ServiceResponse VerifyAction(ServiceRequest request);
}
Вы пытались поймать FaultException вместо этого?
catch (FaultException<WcfException> ex)
{
AppManager.LogException(ex);
}
catch (FaultException unknownFault)
{
AppManager.LogException(unknownFault);
}
Вам нужно будет включить FaultContractAttribute в свой контракт, чтобы это работало.
Что такое WcfException
и это сериализуемо?
В любом случае я предлагаю вам включить трассировку на сервере, как описано в этой статье MSDN - это должно помочь вам диагностировать проблему.
Если вы хотите получить информацию об оригинальном исключении, достаточно использовать:
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>