Getting a FaultException when trying to work with a WCF service

16,642

Solution 1

The problem was in this line:

foreach (var guide in firstAidGuides.ToList())

Apparently calling .ToList() made the whole thing crash. Simply removing .ToList() fixed everything.

Solution 2

Can you try enabling tracing on your WCF Service and also inspect the trace to find out what the error is. Also set the below property to get a complete stack trace of the error

<serviceDebug includeExceptionDetailInFaults="true" />

Solution 3

What I tend to do over WCF is to wrap everything inside my [OperationContract] method in a Try...Catch block; unravel the stack trace of any caught exception and all inner exceptions and stick that as a string into the message of a FaultException that I then re-throw over the soap boundary. Something like this:

public static string GetDebugString(this Exception ex)
{
   var builder = new StringBuilder();
   GetDebugString(ex, builder);
   while ((ex = ex.InnerException) != null)
   {
      GetDebugString(ex, builder);
   }
   return builder.ToString();
}


private static void GetDebugString(Exception ex, StringBuilder builder)
{
    builder.AppendLine(ex.GetType().Name);
    builder.AppendLine();
    builder.AppendLine(ex.Message);
    builder.AppendLine();
    builder.AppendLine(ex.StackTrace);
    builder.AppendLine();
}

[OperationContract]
public void Foo()
{
    this.MakeSafeCall(() => this.UnsafeFoo());
}

public void Unsafe()
{
    // do stuff
}

private void MakeSafeCall(Action action)
{
    try
    {
       action();
    }
    catch (Exception ex)
    {
       throw new FaultException(ex.GetDebugString());
    }
}
Share:
16,642
Nicholas Magnussen
Author by

Nicholas Magnussen

Updated on June 15, 2022

Comments

  • Nicholas Magnussen
    Nicholas Magnussen almost 2 years

    EDIT: Here's my call stack.

    System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(System.ServiceModel.Channels.Message reply, System.ServiceModel.Channels.MessageFault fault, string action, System.ServiceModel.Channels.MessageVersion version, System.ServiceModel.Channels.FaultConverter faultConverter) + 0x124 bytes
    System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.HandleReply(System.ServiceModel.Dispatcher.ProxyOperationRuntime operation, ref System.ServiceModel.Dispatcher.ProxyRpc rpc) + 0x147 bytes
    System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.EndCall(string action, object[] outs, System.IAsyncResult result) + 0xb2 bytes
    System.ServiceModel.dll!System.ServiceModel.ClientBase.ChannelBase.EndInvoke(string methodName, object[] args, System.IAsyncResult result) + 0x1e bytes
    PhoneClient.dll!PhoneClient.ServiceReference1.Service1Client.Service1ClientChannel.EndGetFirstAidGuides(System.IAsyncResult result) Line 420 C# PhoneClient.dll!PhoneClient.ServiceReference1.Service1Client.PhoneClient.ServiceReference1.IService1.EndGetFirstAidGuides(System.IAsyncResult result) Line 284 + 0x7 bytes C# PhoneClient.dll!PhoneClient.ServiceReference1.Service1Client.OnEndGetFirstAidGuides(System.IAsyncResult result) Line 292 + 0x2 bytes C# System.ServiceModel.dll!System.ServiceModel.ClientBase.OnAsyncCallCompleted(System.IAsyncResult result) + 0x20 bytes
    System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously) + 0x66 bytes
    System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously, System.Exception exception) + 0xe bytes
    System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.CallComplete(bool completedSynchronously, System.Exception exception) + 0x8 bytes
    System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishSend(System.IAsyncResult result, bool completedSynchronously) + 0x99 bytes
    System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.SendCallback(System.IAsyncResult result) + 0x1a bytes
    System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously) + 0x66 bytes
    System.ServiceModel.dll!System.ServiceModel.AsyncResult.Complete(bool completedSynchronously, System.Exception exception) + 0xe bytes
    System.ServiceModel.dll!System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(System.IAsyncResult result) + 0x52 bytes
    System.Windows.dll!System.Net.Browser.ClientHttpWebRequest.InvokeGetResponseCallback.AnonymousMethod__8(object state2) + 0x1b bytes mscorlib.dll!System.Threading.ThreadPool.WorkItem.WaitCallback_Context(object state) + 0x18 bytes
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x63 bytes
    mscorlib.dll!System.Threading.ThreadPool.WorkItem.doWork(object o) + 0x47 bytes mscorlib.dll!System.Threading.Timer.ring() + 0x70 bytes

    And the error: The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.

    I'm currenntly working on a Windows Phone 7 application in which I am communicating with a WCF service. I've made it work within one method already. So I that it is possible.

    Here is my class that calls the WCF service

    public partial class FirstAidGuides : PhoneApplicationPage
    {
        public FirstAidGuides()
        {
            InitializeComponent();
            ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
            sc.GetFirstAidGuidesCompleted += new EventHandler<ServiceReference1.GetFirstAidGuidesCompletedEventArgs>(sc_GetFirstAidGuidesCompleted);
            sc.GetFirstAidGuidesAsync();
        }
    
        void sc_GetFirstAidGuidesCompleted(object sender, ServiceReference1.GetFirstAidGuidesCompletedEventArgs e)
        {
            FirstAidGuideText.Text = e.Result[0].Text;
        }
    }
    

    Right now, I'm just trying to get some text written in a textblock, from my result.

    This is the interface of the WCF service.

    [ServiceContract]
    public interface IService1
    {
    
        [OperationContract]
        long CreateCall(string phoneNumber, double longtitude, double langtitude);
    
        [OperationContract]
        List<Model.FirstAidGuide> GetFirstAidGuides();
    }
    

    The method of my service class, that pulls data from a database.

    public List<Model.FirstAidGuide> GetFirstAidGuides()
        {
            DataClasses1DataContext db = new DataClasses1DataContext();
    
            var firstAidGuides = (from f in db.FirstAidGuides select f);
            List<Model.FirstAidGuide> list = new List<Model.FirstAidGuide>();
    
            foreach (var guide in firstAidGuides.ToList())
            {
                Model.FirstAidGuide fa = new Model.FirstAidGuide();
                fa.FirstAidId = guide.FirstAidId;
                fa.Title = guide.FirstAidTitle;
                fa.Text = guide.FirstAidText;
                fa.LastUpdated = (DateTime)guide.LastUpdated;
                list.Add(fa);
            }
            return list;
        }
    

    And just for convenience. The FirstAidGuide class.

    [DataContract]
    public class FirstAidGuide
    {
        [DataMember]
        private string _title;
        [DataMember]
        private string _text;
        [DataMember]
        private DateTime _lastUpdated;
        [DataMember]
        private long _firstAidId;
    
        public long FirstAidId
        {
            get { return _firstAidId; }
            set { _firstAidId = value; }
        }      
    
        public DateTime LastUpdated
        {
            get { return _lastUpdated; }
            set { _lastUpdated = value; }
        }     
    
        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }      
    
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }
    }
    

    I simply cannot get it to do anything. I'm getting a FaultException, which points me in the direction that it cannot handle the response from the WCF service.

    Any help would be appreciated.