Cannot get WCF Exception Shielding to work

Topics: Exception Handling Application Block
Jun 25, 2010 at 3:39 PM

For company guidelines I'm working on a small sample of exception handling for WCF services. However I cannot get it to work, the exception from the code is returned instead of the fault contract.

I'm working in VS 2010 Premium and I have developed a WCF service. This service is tested by pressing F5 so the test client shows up. I assume that invoking the service like that would result in a returned fault contract?

One thing that bothers me is that the Enterprise Library configuration editor says as a warning:

 "Unable to find type WcfExceptionHandling.WcfExceptionHandlingFault, WcfExceptionHandling, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

I added the assembly in the configuration editor using the 'Add from file' option.

My Interface:

namespace WcfExceptionHandling
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [FaultContract(typeof(WcfExceptionHandlingFault))]
        int Subtracter(int number1, int number2);
    }
}
 
My Service:
namespace WcfExceptionHandling
{
    [ExceptionShielding("MyPolicy")]
    public class Service : IService
    {
        public int Subtracter(int number1, int number2)
        {
            return number1 / number2;
        }
    }
}
My Fault Contract:
namespace WcfExceptionHandling
{
    [DataContract]
    public class WcfExceptionHandlingFault
    {
        [DataMember]
        public int FaultCode { get; set; }

        [DataMember]
        public string FaultMessage { get; set; }
    }
}
And my configuration:
<?xml version="1.0"?>
<configuration>

  <configSections>
    <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <exceptionHandling>
    <exceptionPolicies>
      <add name="MyPolicy">
        <exceptionTypes>
          <add name="All Exceptions" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="ThrowNewException">
            <exceptionHandlers>
              <add type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                exceptionMessage="This is a shielded exception!" faultContractType="WcfExceptionHandling.WcfExceptionHandlingFault, WcfExceptionHandling, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
                name="Fault Contract Exception Handler">
                <mappings>
                  <add source="{Guid}" name="FaultCode" />
                  <add source="{Message}" name="FaultMessage" />
                </mappings>
              </add>
            </exceptionHandlers>
          </add>
        </exceptionTypes>
      </add>
    </exceptionPolicies>
  </exceptionHandling>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  
</configuration>

 


Jun 28, 2010 at 2:29 AM
Edited Jun 28, 2010 at 2:39 AM

If you have already followed the steps mentioned in this blog, do you mind sending a sample project which repros this? 

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Aug 10, 2010 at 6:16 PM

Hi Sarah,

I followed every step and the fault does get logged and returned to the client.  However, every exception is coming back as the generic  System.ServiceModel.FaultException type and I'm expecting to catch my defined type.  Basically, my catch block

catch (FaultException<ServiceFault> ex)

{

    ServiceFault fault = ex.Detail;

    Console.WriteLine(fault.MessageText);

    Console.WriteLine(fault.Id);

}

will not be able to catch anything.  It's all going to the general FaultException block.  Also, in the config for the Fault Contract Exception Handler, there's also a "Exception Message" textbox where I can fill in any text.  How's this different than the ex.Detail.MessageText?  Help...

Aug 11, 2010 at 1:28 AM

You're sure you specified the fault contract type by using FaultContractType attribute in the interface method definition? You can send us your sample solution which repro this so we could take a look at it.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Aug 11, 2010 at 5:15 PM

Hi Sarah,

Yes, I did specify that.  As I tried to gather some code to send to you, I played around with where I defined my ServiceFault class so I can just send you one code file then it started to work.  I moved my class back to where it was and it continues to work.  I still don't know why it didn't work before.  Of course, with all these moving around, all I did was copy/paste/change config for fault contract to point to the right location, etc... anyway, things are working now so thanks a lot for your response.

May 18, 2011 at 8:14 AM

Hi,

I am having exactly the same issue. I.e. the Enterprise Library Configuration Tool says 'Unable to find type...' and when trying to get the shielding to work, I get a standard FaultContract instead of the wanted FaultContract<T>.

Any idea what resolved the issue? Preferably more tangible than 'playing around' with the code.

As opposed to referred blog post I use Entlib 5.0.

Regards,

/Jonas 

May 18, 2011 at 8:29 AM

Hi Jokarl,

Can you send us a sample repro project of your issue?

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

May 18, 2011 at 9:28 AM

Hi,

Wow. Quick response. :-)

Updating the Service Reference did the trick for me.

/Jonas

Aug 11, 2011 at 1:51 PM

Hi,

I tried the same i could not get it working. Can you please upload the sample project . I have been trying for almost a day in vain. Can you please help 

 

Aug 12, 2011 at 2:31 AM

Hi glpathy,

Kindly post your email address here or drop us a message to entlib.support@avanade.com.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
Contact Us

 

 

Aug 12, 2011 at 4:57 AM

Hello,

Thank you for a quick response. I have sent a mail with a subject as "Exception Schielding Help Required" from my mail id .

Please drop me a mail on

lakshmipathy.babu@ust-global.com

 

 

Aug 12, 2011 at 5:13 AM

Got it! We'll look into this and get back to you for updates.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
Contact Us

Aug 15, 2011 at 5:06 AM

Hi glpathy,

We got some reference errors after compiling your application. Anyway, did you received exception while running your application? Also, try to rename your policy to "WCF Exception Shielding" and see if this works?

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
Contact Us

Aug 16, 2011 at 7:21 AM
Hello,
 
Thank you for the response.
 
I changed the policy name to WCF Exception Shielding and retried still with no luck. I have retached the file  and send it back.
 
Aug 16, 2011 at 9:08 AM

Hi,

I got your solution. It seems you are not using a WCF service. Can you check if this is the case? Anyway I'll send you my sample solution of WCF Exception Shielding. Kindly check it.  

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
Contact Us

Aug 16, 2011 at 1:11 PM
I have self hosted WCF service using console application. Can you please attach a sample solution and send it
Aug 17, 2011 at 2:58 AM

I've attached the sample solution on my last email. Kindly check it.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
Contact Us

Aug 17, 2011 at 5:22 AM

Thank you so much. Your attached solution works like a champ.

Jan 5, 2012 at 5:11 AM

Hi

I am facing the same problem . Can you please send me the sample solution too?

Thanks.

Jan 5, 2012 at 6:14 AM

See the WCF Exception Shielding With Logging Exception Handler project on the Sample Projects page.

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

Jan 16, 2012 at 3:28 PM

Hi, 

 

I've a ditto problem and I'm struggling with it for ages. can I send my snippet to your support id? would you be able to please help me?

 

Kavya

Jan 16, 2012 at 3:39 PM

Here is my code. what am I dpong wrong? :(

 

Service:

 [ExceptionShielding("FaultPolicy")]

    public class ManagementService : IManagementService

    {

 

public List<Snapshot> SnapshotData (int surveyYear, int siteId)

        {

            var result = new List<Snapshot>();

            ExceptionManager em = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();

 

            //try

            //{

            em.Process(() =>

            {

                using (var repository = new Repository())

                {

                    result = repository.GetReleaseSnapshotData(surveyYear, siteId);

                }

               

            }, "FaultPolicy");

               

            return result;

          

           

        }

}

 

[ServiceContract(Name = " IManagementService)]

       public interface IManagementService

    {

        [OperationContract]

        [FaultContract(typeof(FaultContracts.ServiceFaultContract))]

        List<Snapshot> SnapshotData (int surveyYear, int siteId);

 

}

Web.config

<exceptionHandling>

    <exceptionPolicies>

      <add name="FaultPolicy">

        <exceptionTypes>

          <add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException">

            <exceptionHandlers>

              <add name="ServiceFaultHandler" type="ServiceFaultHandler, ExceptionHandler"

                   exceptionMessage="Service Fault Exception: The service operation threw an exception."

                   detailsExceptionType=" ServiceFaultContract,Service"/>

                  

            </exceptionHandlers>

          </add>

        </exceptionTypes>

      </add>

    </exceptionPolicies>

  </exceptionHandling

 

Servicefaultcontract

 

[DataContract]

    [Serializable]

    public class ServiceFaultContract :Exception

    {

        [DataMember]

        public Exception detailsExceptionType

        {

            get;

            set;

        }

        [DataMember]

        public string message

        {

            get;

            set;

        }

        public ServiceFaultContract()

        {

        }

      

        public ServiceFaultContract(string message, Exception inner):base(message,inner)

        {

        }

        public ServiceFaultContract(Exception inner)

            : base(inner.Message, inner)

        {

        }

        protected ServiceFaultContract(

          System.Runtime.Serialization.SerializationInfo info,

          System.Runtime.Serialization.StreamingContext context)

            : base(info, context)

        {

        }

    }

 

 

I’m calling it like this

   [TestMethod]

        public void TestMethod1()

        {

            try

            {

                var f = new ClientRepository().SnapshotData(2013, 2);

            }

            catch (FaultException<ServiceFaultContract> e)

            {

                var f = e.Detail;

                Console.WriteLine(f.Message + 1);

                //Console.WriteLine(f.detailsExceptionType);

            }

        

            catch (FaultException ex)

            {

                Console.WriteLine(ex.GetType().FullName + "\n" + ex.Message);

            }

            catch (Exception ex)

            {

               // Assert.IsInstanceOfType(ex, typeof(ServiceFaultContract));

                Console.WriteLine(ex.GetType().FullName + "\n" + ex.Message);

            }

        }

 

My problem is, it never goes to any catch block except Exception. Please help. What am I doing wrong? I’m basing this on Burges sample

 

Jan 16, 2012 at 9:43 PM

I'm not following the code sample 100%.  Some questions/comments:

  • "FaultPolicy" is applied twice in the same method call: once through Shielding and once through the ExceptionManager.  Is there a reason why?
  • The configuration is specifying to use the following handler: ServiceFaultHandler, ExceptionHandler; Is this a custom handler?  If so, what does it do?
  • What is ClientRepository?  Is it a WCF proxy class?  If it's not then the testing is not using WCF.
  • By "Burges Sample" do you mean Guy Burstein's Blog?  That blog also has a download of the project you can use as a starting point.
  • There is no reference in the configuration to the FaultContractExceptionHandler so it doesn't look like WCF Exception Shielding is configured.

I would expect the configuration to look something like this:

  <exceptionHandling>
    <exceptionPolicies>
      <add name="Policy">
        <exceptionTypes>
          <add name="All Exceptions" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="ThrowNewException">
            <exceptionHandlers>
              <add type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                faultContractType="MyAssembly.ServiceFaultContract, MyAssembly"
                name="Fault Contract Exception Handler">
                <mappings>
                  <add source="Message" name="message" />
                </mappings>
              </add>
            </exceptionHandlers>
          </add>
        </exceptionTypes>
      </add>
    </exceptionPolicies>
  </exceptionHandling>

Then you can remove the ExceptionManager code (" em.Process(() =>") and let the exception bubble up to the Exception Shielding (unless you want to perform some pre-shielding handling (replace, wrap, etc.).

 

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

Jan 17, 2012 at 7:19 AM

Hi Randy,

Sorry. i thought I'd attached servicefault handler. yes. it's custom exception handler. The reason I've gone ahead with the custom one is cuz I've other attributes to attach along with the message and type and few dynamically.

I've answered below to your comments

  • "FaultPolicy" is applied twice in the same method call: once through Shielding and once through the ExceptionManager.  Is there a reason why?
  • This is by mistake. I've taken off the em.process
  • The configuration is specifying to use the following handler: ServiceFaultHandler, ExceptionHandler; Is this a custom handler?  If so, what does it do?
  • this code is exactly like in Guy's sample. 
  • What is ClientRepository?  Is it a WCF proxy class?  If it's not then the testing is not using WCF.
  • yes. it's a proxy
  • By "Burges Sample" do you mean Guy Burstein's Blog?  That blog also has a download of the project you can use as a starting point.
  • Yes. That's what I meant. Hate to say this but my code is exactly like Guy's with slight modifications to start with.
  • There is no reference in the configuration to the FaultContractExceptionHandler so it doesn't look like WCF Exception Shielding is configured.
  • I quite didn't understand this. I've to configure exceptionshielding? can you please help? sorry i'm very new to this entlib and still getting my head around

I removed em.process as you mentioned and now it goes into  catch (FaultException ex) block. thanks for the same. I still want it to get into  catch (FaultException<ServiceFaultContract> e) block. How can I make this work? the fault handler is same as Guy's

  /// <returns><para>Modified exception to pass to the next exceptionHandlerData in the chain.</para></returns>                public Exception HandleException(Exception exception, Guid handlingInstanceId)        {            return WrapException(                exception,                ExceptionUtility.FormatExceptionMessage(DetailExceptionMessage, handlingInstanceId));        }
        /// <summary>        /// Wraps the original exception with FaultException.        /// </summary>        /// <param name="originalException"></param>        /// <param name="detailsExceptionMessage"></param>        /// <returns></returns>        private Exception WrapException(Exception originalException, string detailsExceptionMessage)        {            // Create the detail exception            object[] extraParameters = new object[] { detailsExceptionMessage };                        Exception detail = (Exception)Activator.CreateInstance(DetailExceptionType, extraParameters);
            Type faultExceptionType = typeof(FaultException<>);            Type faultBindedExceptionType = faultExceptionType.MakeGenericType(DetailExceptionType);
            // Create a meaningful fault reason            FaultReason reason = new FaultReason(originalException.Message);
            // Construct a new fualtException with generic type            extraParameters = new object[] { detail, reason };            Exception detail2 = (Exception)Activator.CreateInstance(faultBindedExceptionType, extraParameters);            return detail2;        }

 

 

 

Jan 17, 2012 at 8:02 AM

The blog you are talking about is not the blog that is being referenced in this thread.  I recommend reading it since it explains how exception shielding works and how to get exception shielding set up.  Actually, the blog entry you are referencing is using Enterprise Library 2.0 and WCF which pre-dates the Enterprise Library 3.1 WCF exception shielding.  Instead of using your own custom exception shielding you should use the out of the box exception shielding.

If I were to guess what your issue is I would guess that you are getting a "The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state." because the type in your config file in incorrect.  In the config it has <add name="ServiceFaultHandler" type="ServiceFaultHandler, ExceptionHandler" whereas I would have thought the type would be something more like "ExceptionHandler.ServiceFaultHandler, ExceptionHandler".

If you are not sure what is happening in the WCF service then you can enable tracing:

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

If you have any configuration issues you will see exceptions in the generated traces.svclog.  Something like:

The type ServiceFaultHandler, ExceptionHandler from configuration could not be created. (C:\\WCFExceptionHandler\WCFExceptionHandler\Echo.Service\bin\Debug\Echo.Service.exe.Config line 14)

But, as I said, you should change your approach to use Exception Shielding. 

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

Jan 17, 2012 at 8:18 AM

Hi Randy, 

Thanks for the input. the servicefaulthandler name is correct in the webconfig at my end. I should've mentioned to you earlier. I removed the namespace before posting here as it has my company details in it(privacy reasons).  Actual config has fulll name space along with the assembly data.

I also apologise for posting it in wrong thread. I needed custom fault handler as we've to add many more properties. so i followed Guy's blog Only to write custom handlers and nothing else. 

As mentioned earlier, after your suggestion, I removed em.process and now it goes to  catch (FaultException ex) block. But I can't seem to make it go to catch (FaultException<ServiceFaultContract> e) 

I really need your help on this. if I remove shielding and use em.process, it goes to catch(Exception e) block.

Once I sort this out, I'll definitely read more on exceptionShielding you've suggested.

 

Please help

Jan 17, 2012 at 8:35 AM
Edited Jan 17, 2012 at 8:39 AM

What exception are you getting?  Did you try tracing?

You should also remove the ExceptionShielding attribute since you aren't using exception shielding.

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

Jan 17, 2012 at 9:27 AM

Hi Randy,

 

the exception is "could not open conn to db. System.exception.communicationexception". this is a valid exception as per my inputs. but I wanted this wrapped in FaultException<serviceFaultContract> which is not doing at the moment.

 

when you say "remove exceptionshielding", I should be using process then? because I do not want to be havng try-catch in every method.

 

Jan 17, 2012 at 12:43 PM
AvanadeSupport wrote:

I've attached the sample solution on my last email. Kindly check it.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
Contact Us

Hi, 

Can I get this sample solution as well? Would really help me. I've same problem and I'm exhausted trying it. I'd posted in the last response to this but as Randy suggested, I'm now following above blog. can I send you my sample solution as well?

Jan 17, 2012 at 12:59 PM

I changed it to as below

 

  public class ManagementService : IManagement

 

{

   public List SnapshotData (int surveyYear, int siteId)

        {

                using (var repository = new Repository())

                {
			//repository
			return repository.GetReleaseSnapshotData(surveyYear, siteId);

                }

            
        }

}

 
[ServiceContract(Name = "IManagementService")]
 [ExceptionShielding]

       public interface IManagementService

    {

        [OperationContract]

        [FaultContract(typeof(ServiceFault))]

        List<SnapshotData> (int surveyYear, int siteId);

}

    [TestMethod]

 

        public void TestMethod1()

        {

            try

            {

                var f = new ClientRepository().SnapshotData(2013, 2);

            }

            catch (FaultException e) //never reaches this block 

            {

                var f = e.Detail;

                Console.WriteLine(f.Message + 1);

                //Console.WriteLine(f.detailsExceptionType);

            }

        

            catch (FaultException ex)

            {

                Console.WriteLine(ex.GetType().FullName + "\n" + ex.Message);

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.GetType().FullName + "\n" + ex.Message);

            }

        }

web.config;
 
    
I'm also posting client repository class
public partial classManagementServiceClient : FClientBase, IManagementService
    {
        public List SnapshotData(int surveyYear, int siteId, List lstSurveyInstanceId, List lstBranchId)
        {
            return base.Channel.SnapshotData(surveyYear, siteId, );
        }
{

 

Jan 17, 2012 at 1:30 PM
Edited Jan 17, 2012 at 1:31 PM
kavsshiva wrote:

Hi, 

Can I get this sample solution as well? Would really help me. I've same problem and I'm exhausted trying it. I'd posted in the last response to this but as Randy suggested, I'm now following above blog. can I send you my sample solution as well?

There is a project located on the Sample Projects page.  Also, posts on this thread mentioned the blog WCF Exception Handling with Exception Handling Application Block Integration which has a sample solution.

Perhaps if you post a project that reproduces your issue it would help identify the issue.

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

Jan 17, 2012 at 1:34 PM

Hi Randy, 

I hate to admit. but I changed exactly like the one the blog suggests. I still don't understand what am I doing wrong.  in my prev post, I attached all teh code snippets. 

Please help. I'm going mad. is this anything to do with the client ? 

public partial classManagementServiceClient : FClientBase, IManagementService
    {
        public List SnapshotData(int surveyYear, int siteId, List lstSurveyInstanceId, List lstBranchId)
        {
            return base.Channel.SnapshotData(surveyYear, siteId, );
        }

 public class

FClientBase

<TChannel> : ClientBase<TChannel> where TChannel : class    {          #region Constructor        public FClientBase()        {        }

Jan 17, 2012 at 1:40 PM
randylevy wrote:
kavsshiva wrote:

Hi, 

Can I get this sample solution as well? Would really help me. I've same problem and I'm exhausted trying it. I'd posted in the last response to this but as Randy suggested, I'm now following above blog. can I send you my sample solution as well?

There is a project located on the Sample Projects page.  Also, posts on this thread mentioned the blog WCF Exception Handling with Exception Handling Application Block Integration which has a sample solution.

Perhaps if you post a project that reproduces your issue it would help identify the issue.

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

I will surely try to simulate it. but can't send the project for security reasons.

Jan 17, 2012 at 2:54 PM

Hi Randy, 

 

I've sent it to entlib.support@live.com with subject "Attention Randy: ExceptionShielding not working".

surprisingly, the simulator I've sent you works. but I hope you get the idea of what my project looks like.

Please help

Jan 18, 2012 at 11:21 AM

Unfortunately, a working solution does not help pinpoint what issue you are seeing.  

I would recommend taking the working solution and modify it bit by bit testing as you go to ensure that it is still working at every step of the way.  That way you will know what change caused the problem.  If your actual solution is not working but the sample is working I would modify the working sample to try to replicate the exact approach you will take with the actual solution (custom handlers, assembly structures, configuration etc.) testing every change as you go.

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

Jan 18, 2012 at 11:37 AM

Hi Randy, 

yes. you're right. thats what i did and figured out the issue. 

the contract name wasnt full name in the config. It was nothing to do with entlib. 

Thanks for taking time on it. appreciate it.