WCF FaultException
Solution 1
For simplifying the approach of throwing a FaultException
from the service and catching and processing it at the client side kindly follow this code:
Service:
public bool UpdateSpotCheckInventory(SpotCheck transferObject)
{
bool blnUpdated = false;
try
{
blnUpdated = SpotCheckCollectionGateway.UpdateData(transferObject);
LogMessage.WriteEventLog("SpotCheck records updated successfully", "Ryder.ShopProcessService.SOA", 3, null);
return blnUpdated;
}
catch (Exception ex)
{
//throw fault exception here on service
throw new FaultException("A fatal exception occurred while processing your request", new FaultCode("1000"))
}
}
Client:
catch (FaultException ex)
{
ex.Detail.ApplicationID = "ShopProcessService";
ex.Detail.LogEventType = LogEventTypeEnum.Error;
serviceClient.Abort();
// You can also access the custom message and error code sent from the service...
String customErrorCode = ex.Code.Name;
String customErrorMessage = ex.Reason;
}
I'm sure this would solve your problems. :-)
Solution 2
Please try define the CustomFault(MathFault in this example) as a data contract rather than Operation Contract, like:
[DataContract]
public class MathFault
{
//...
}
At the client side:
static void Main(string[] args)
{
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
try
{
int value1 = 22;
int value2 = 0;
int result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
client.Close();
}
catch (FaultException<MathFault> e)
{
Console.WriteLine("FaultException<MathFault>: Math fault while doing " + e.Detail.Operation + ". Problem: " + e.Detail.ProblemType);
client.Abort();
Console.ReadLine();
}
}
See more: Fault Contract
sagesky36
Updated on June 04, 2022Comments
-
sagesky36 almost 2 years
When building a WCF service, if I don't include my contract for the FaultException in the service, I'm able to create a WCF service reference on the client with all of the members included in the Reference.cs file.
If I include my FaultException contract, two things happen.
In the WCF test client, I have a red "X" next to the contract name (CreateFaultMessage)
When I create the WCF service reference, not all of the members are included in the Reference.cs file.
I am hoping somebody will be able to inform me what I'm doing incorrectly as far as creating my FaultException contract since I am not a WCF expert.
Below, is the code declaration of my contract in the interface.
[OperationContract] [FaultContractAttribute(typeof(LogEventArgs), ProtectionLevel = ProtectionLevel.None)] Exception CreateFaultMessage(Exception ex, string method);
Below, are methods in the class which implement the interface. Notice the call to the CreateFaultMessage method in the catch block of the PostTransmissionRecord method.
public bool PostTransmissionRecord(TransmissionRecord transmissionRecord) { bool blnUpdated = false; try { blnUpdated = TransmissionRecordGateway.InsertData(transmissionRecord); LogMessage.WriteEventLog("Transmission records updated successfully", "Ryder.ShopProcessService.SOA", 3, null); return blnUpdated; } catch (Exception ex) { LogMessage.WriteEventLog("Class: ShopProcessService" + CrLf + "Method: PostTransmissionRecord" + CrLf + "Error: " + ex.Message + CrLf + "InnerException: " + ex.InnerException + CrLf + "Source: " + ex.Source + CrLf + "StackTrace: " + ex.StackTrace, "Ryder.ShopProcessService.SOA", 1, null); IssueRemedyTicket("Class: ShopProcessService" + CrLf + "Method: PostTransmissionRecord" + CrLf + "Error: " + ex.Message + CrLf + "InnerException: " + ex.InnerException + CrLf + "Source: " + ex.Source + CrLf + "StackTrace: " + ex.StackTrace); CreateFaultMessage(ex, "UpdateSearchInventory"); return blnUpdated; } } public Exception CreateFaultMessage(Exception ex, string method) { LogEventArgs detail = new LogEventArgs(); detail.ApplicationID = "ShopProcessService"; detail.ExceptionMessage = ex.Message; detail.LogEventType = LogEventTypeEnum.Error; detail.Method = method; detail.Source = ex.Source; detail.StackTrace = ex.StackTrace; if (ex.InnerException != null) detail.InnerExceptionMessage = ex.InnerException.ToString(); else detail.InnerExceptionMessage = null; throw new FaultException<LogEventArgs>(detail); }
UPDATED CODE
DataContract class
namespace Ryder.Enterprise.DataTransferObjects { [Serializable, DataContract(Name = "LogEventArgs", Namespace = "http://www.Ryder.com/SOA/DataContracts/2014/02/17")] public class LogEventArgs { private string applicationID; private string method; private LogEventTypeEnum logEventType; private string exceptionMessage; private string innerExceptionMessage; private string stackTrace; private string source; [DataMember(Name = "ApplicationID")] public string ApplicationID { get { return applicationID; } set { applicationID = value; } } . . .
Service method throwing FAULTEXCEPTION
public bool UpdateSpotCheckInventory(SpotCheck transferObject) { bool blnUpdated = false; try { blnUpdated = SpotCheckCollectionGateway.UpdateData(transferObject); LogMessage.WriteEventLog("SpotCheck records updated successfully", "Ryder.ShopProcessService.SOA", 3, null); return blnUpdated; } catch (Exception ex) { //throw fault exception here on service return blnUpdated; } }
CLIENT CODE CATCHING THE FAULTEXCEPTION
catch (FaultException<LogEventArgs> ex) { ex.Detail.ApplicationID = "ShopProcessService"; ex.Detail.LogEventType = LogEventTypeEnum.Error; serviceClient.Abort(); }
-
sagesky36 about 10 yearsReferring to the Updated Code. This question is for the DataContract class: Haixia, I very much appreciate your help :) I modified my code, but am unsure how to throw the FaultException. I have the following set up now on my service now: I'm referencing a class that contains the DataContract as partially seen below. I think I would only need the applicationID and logeventType as the FaultException would seem to carry over the other properties I have listed. Please let me know if that is true.
-
sagesky36 about 10 yearsThis question is for the Service method throwing the FAULT exception. This is the method where I want to throw the FaultException. Syntactically, how would that look? Not sure how to place it in the Catch block or if even the Catch block is correct.
-
sagesky36 about 10 yearsThis question pertains to the CLIENT CODE CATCHING THE FAULTEXCEPTION. This is what I have on my client now. When the FaultException gets hit, it is transmitted back to the calling service and they would receive the exception message with the appropriate properties including the ex.Message, stacktrace, method, etc?
-
sagesky36 about 10 yearsFinally, the last question: what would a Catch block look like on the receing end of getting the FaultException back from a service?
-
dhrumilap about 10 yearsCheck my new answer where I've shown how to throw a FaultException with custom message and error code in the service and how to handle it in the client.
-
sagesky36 about 10 yearsHaixia, thanks for the update. I understand. One last question... If I include properties in the LogEventArgs class, can I or do I need to place the following code before aborting the client? ex.Detail.ApplicationID = "ShopProcessService"; ex.Detail.LogEventType = LogEventTypeEnum.Error; ex.Detail.FaultCode = ex.Code; ex.Detail.Reason = ex.Reason; ex.Detail.ExceptionMessage = ex.Message; or would the ExceptionMessage, etc, be redundant?