WCF fault handling

给你一囗甜甜゛ 提交于 2019-12-12 11:41:13

问题


Q How can I get the original exception (occurred on the server) on the client side?

I am working with a self-hosted WCF service and C# 4 and trying to set up proper exception handling.

I have a client that looks like this

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;
}

And service implementation

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;
}

Service web.config has

<behaviors>
    <serviceBehaviors>
        <behavior>
            <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
    </serviceBehaviors>
</behaviors>

This is my original exception

And this is what I get on the client

If needed I can post full details on the client side, however the exception on the client does not have any reference to the original one.

Update
This is my interface with defined 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);
}

And this is my WcfException class

[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; }
}

回答1:


Have you tried to catch a FaultException instead?

catch (FaultException<WcfException> ex)
{
   AppManager.LogException(ex);
}
catch (FaultException unknownFault)
{
   AppManager.LogException(unknownFault);
}

You will need to include a FaultContractAttribute in your contract for this to work.




回答2:


What is WcfException and is it serializable?

In any case, I suggest you enable tracing on the server as described in this MSDN article - this should help you diagnose the problem.




回答3:


If you want to have information about original exception it is enough to use:

<behaviors>
    <serviceBehaviors>
        <behavior>
            <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
    </serviceBehaviors>
</behaviors>



回答4:


Thanks for all your answers. My problem was in the service interface, namely in the Action property of FaultContractAttribute, it pointed to the incorrect 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);
}

I solved it by removing all other properties (to be determined automatically) and left only the type of 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);
    }


来源:https://stackoverflow.com/questions/6250367/wcf-fault-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!