Обработка ошибок 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>
Другие вопросы по тегам