Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Exception Thrown by a Web Service not seen as same type by the Client (using shared assemblies)

I have created a custom exception InvalidSessionException. However when trying to catch or evaluate if the exception raised is of that type, it doesn't work. Meaning that it both EX is and Catch Ex, don't evaluate to InvalidSessionException

try 
{
    acc = this.fda.GetAccountHeader(this.selectedTicket.AccountId);
}  
catch (Exception ex) 
{
    if (ex is Enterprise.Data.InformationModel.CustomExceptions.InvalidSessionException) 
    {
        this.lblError.Text = Resources.Resource.error_sessionedTimedOut;
        this.MPError.Show();
    }
    return;
}

I have also tried (without any difference in results)

catch (Enterprise.Data.InformationModel.CustomExceptions.InvalidSessionException ex) 
{
    this.lblError.Text = Resources.Resource.error_sessionedTimedOut;
    this.MPError.Show();
    return;
} 
catch (Exception ex) 
{
    return;
}

From what I can tell the exception being thrown is of the correct type.

enter image description here

More Information:

ex.GetType().FullName = "System.ServiceModel.FaultException1[[System.ServiceModel.ExceptionDetail, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"

Reuse Types is enabled on the service? enter image description here

like image 225
owen gerig Avatar asked Feb 11 '14 20:02

owen gerig


2 Answers

Credit where credit is due
Nintey-nine percent of the credit of this answer goes to the comment left by Adriano Repetti on this page. I just tested this solution out myself as I was having the exact same problem as described in the question above.

The Problem
Configure Service Reference window assemblies section

In reference to the "Configure Service Reference" modal window; just because you select “Reuse types in all referenced assemblies” does not mean that it will actually do it – it seems to be a lazy operation and basically those references will be made if the auto generation code happens to match it up.

The Solution
Therefore if you actually check mark what you care about, it seems like it is guaranteed to be used instead of maybe. This is accomplished by changing the radio button from “Reuse types in all referenced assemblies” to “Reuse types in specified referenced assemblies” (second radio button option).

My Supporting Observations
It seems like this specifically affects FaultExceptions, I don’t know why, but it does. My FaultExceptions in my project were being generated under the service reference's namespace instead of re-using them from the referenced assembly.

What is especially puzzling is that the namspace is specifically described when you look at the Reference.cs of the service reference code. Even so, it was not working until I did what I described above. Lastly I just want to point out that this is an excellent example of "breaking canon" or "not being canonical".

like image 180
dyslexicanaboko Avatar answered Nov 16 '22 08:11

dyslexicanaboko


I believe you need to use strongly typed FaultException<T>. Something like...

DISCLAIMER: the following code has not been tested

SERVER SIDE

[ServiceContract]
public interface ISampleService
{
  [OperationContract]
  [FaultContractAttribute(typeof(InvalidSessionException)]
  void SampleMethod();
}

void SampleMethod()
{
  ...
  throw new FaultException<InvalidSessionException>();
}

CLIENT SIDE

...

try
{
   _wcfChannel.SampleMethod();

   catch (FaultException<InvalidSessionException> ex)
   {
      // take appropriate action
   }
}

ADDITIONAL READING

  • MSDN: FaultException
  • remondo.net: Using WCF Typed Fault Exceptions (a simple example)
  • iDesign: WCF Fault Contract (sample code)
  • CodeProject: A Beginner's Tutorial for Understanding Exception Handling, FaultExceptions and FaultContracts in WCF
like image 32
Pressacco Avatar answered Nov 16 '22 08:11

Pressacco