Silverlight with WCF logging not working as expected

Topics: Logging Application Block
Aug 29, 2012 at 3:27 PM
Hi,

I have a silverlight application which invokes wcf to process data. I have implemented the exception handling part in wcf using fault exception and throw it back to Silverlight.

Here is my web.config:

<system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="silverlightFaults" type="WCF.SilverlightFaultBehavior, WCF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="SilverlightFaultBehavior">
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="False" />
         </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <customBinding>
        <binding name="Service.customBinding0">
          <binaryMessageEncoding />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
    <services>
      <service name="WCF.Service">
        <endpoint address="" binding="customBinding" behaviorConfiguration="SilverlightFaultBehavior"
                  bindingConfiguration="Service.customBinding0"
          contract="WCF.IInterface" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

 

Here is the interface:

 [ServiceContract]
    public interface IInterface    {
        [OperationContract]
        [FaultContract(typeof(FaultDetails))]
        IList<APP> GetAllApplications();
    }

Here is the implementation of the interface:

 

[SilverlightFaultBehavior]    
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class VisualizationService : IVisualization
    {
        private const string SERVICELAYERERROR = "Service Layer Error";
        private const int ERRORCODE = 102;
        
              public IList<APP> GetAllApplications()
        {
            IList<APP> lstApps = new List<APP>();

            try
            {
                DataWrapper dataWrapper = new DataWrapper();
                lstApps = dataWrapper.GetAllApplications();
            }
            catch (FaultException<FaultDetails> e)   
            {
                throw e;
            }
            catch (Exception ex)
            {
                throw new FaultException<FaultDetails>(new FaultDetails() { FaultCode = ERRORCODE, FaultMessage = ex.Message },
                    new FaultReason(SERVICELAYERERROR));
            }

            return lstApps;
        }
}
  [DataContract]
    public class FaultDetails
    {
        [DataMember]
        public string FaultMessage { get; set; }
        [DataMember]
        public int FaultCode { get; set; }
    }

This works fine for me. But when i try to log an exception from Silverlight. I simply invoke a wcf method by passing the exception which will use the exception block and log it.

But i am unable to invoke the below method in the wcf. 

 public void InsertException(Exception ex)
        {
            try
            {
                bool rethrow = false;
                rethrow = UserInterfaceExceptionHandler.HandleException(ref ex);
            }
            catch (Exception exp)
            {
            }
        }

Due to the following error: 

There was an error while trying to serialize parameter http://tempuri.org/:ex. The InnerException message was 'Type 'System.DivideByZeroException' with data contract name 'DivideByZeroException:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, 
by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  
Please see InnerException for more details.

Please help me where i have gone wrong and what's the solution.

How can I log an exception from silverlight using WCF method by just passing the exception that has occured?

Thanks

Anita.

Aug 29, 2012 at 11:53 PM
Edited Aug 30, 2012 at 12:23 AM

I'm a bit confused as I don't see the Enterprise Library features being used in the Silverlight client.

The error you are seeing is because the service accepts an exception but you are passing in a derived type which WCF does not like.  To get around this you usually add the KnownType attribute but this is not practical for all possible exceptions.  

The easiest approach would be to extract the pertinent pieces of information from the exception and pass those to your service.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Aug 30, 2012 at 5:54 AM

Hi Randy,

Thanks for the response.

The above give code snippets are of wcf and the exception handling and logging features of Enterprise Library is incorporated in the WCF and not on Silverlight layer.

Here is a snippet of silverlight method:

void Visualization_Loaded(object sender, RoutedEventArgs e)
        {            
            try
            {
                // Fetch client context and then the user's name
                clientContext = context();

                if (clientContext != null)
                {
                    currentWeb = clientContext.Web;
                    clientContext.Load(currentWeb);
                    objCurrentUser = clientContext.Web.CurrentUser;
                    clientContext.Load(objCurrentUser);
                    clientContext.ExecuteQueryAsync(GetCurrentUserSucceeded, GetCurrentUserFailed);
                }               
            }
            catch (Exception ex)
            {
                service.InsertExceptionAsync(ex);
                Dispatcher.BeginInvoke(() => busyInd.IsBusy = false);
            }
        }

I haven't implemented the Enterprise Library for silverlight. I thought just by passing the exception to the wcf layer and then by invoking exception handling block should log the error.

Please do suggest me what needs to be done.

I tried using KnownType attribute too, but that did not stop the error from occuring.

 

Thanks

Anita.

 

Aug 30, 2012 at 7:24 AM

OK, I understand.  Since you are using .NET on the client and server and it sounds like you own both sides of the wire you could try using the NetDataContractSerializer.  The article WCF — Using the NetDataContractSerializer to share your type gives some guidance.

Or you could just change your interface to pass in the various pieces of information that you are interested (StackTrace, Message, etc.) in as simple types. 

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Aug 30, 2012 at 10:45 AM

Hi Randy,

So if I try to send bits of information to WCF. How do I log it using Enterprise Library?

Since for every layer (UI, Business and Data Access), I am handling the exception through enterprise library and logging it. Similarly exception handler is created for UI as well. If I do not have an exception type and instead pass simple types, then how can I construct an exception to pass to the handler?

Service code:

public void InsertException(Exception ex)
        {
            bool rethrow = false;
            rethrow = UserInterfaceExceptionHandler.HandleException(ref ex);            
        }

 

 public static class UserInterfaceExceptionHandler
   {

      public static bool HandleException(ref System.Exception ex)
      {
          bool rethrow = false;
          try
          {
               rethrow = ExceptionPolicy.HandleException(ex, Constants.EXCEPTION_POLICY_USERINTERFACE);
          }
          catch (Exception exp)
          {
              ex = exp;
          }
          return rethrow;
      }
   }

Thanks

Anita.

 

Aug 30, 2012 at 9:40 PM

Hi,

Are you trying to have the Silverlight UI use Enterprise Library on the server side to handle and log exceptions.   If so, I would recommend using the Silverlight Integration Pack for Microsoft Enterprise Library 5.0.  This will let you use Enterprise Library Exception Handling block on the Silverlight client (including logging exception handler) as well as a remote logging service to log that exception on the server.

See http://msdn.microsoft.com/en-us/library/hh852705(v=pandp.51) for a variety of resources regarding the Silverlight Integration Pack.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Aug 31, 2012 at 5:54 AM

Hi Randy,

I have gone through some of those samples but I'm still not clear on how it works.

Are there any other samples too, which can describe in detail on remote service logging using Enterprise pack for silverlight.

Currently, I have just handled it by passing the simple typed values of the Exception from Silverlight to WCF and then log it.

But there is a small problem in log file name that gets created.

I'm using Rolling Flat File Trace Listener and I'm expecting it to get created with the Timestamp, which is not happening.

I have started a new discussion for the same:

Filename does not get created with the timestamp

Please can you help on this one too.

Thanks,

Anita.

Sep 1, 2012 at 6:47 AM

The most thorough discussion of Silverlight will be the Developer's Guide but for a shorter introduction you could watch these videos on exception handling and logging: 

http://channel9.msdn.com/posts/Enterprise-Library-for-Silverlight-Exception-handling-demo
http://channel9.msdn.com/posts/Enterprise-Library-for-Silverlight-Logging-demo

You can also download the StockTrader V2 Reference Implementation or look at the Silverlight Remote Service Trace Listener Sample on the Samples Page.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com