WCF FaultException

在构建WCF服务时,如果我没有在服务中包含我的FaultException合同,我可以在客户端上创建一个WCF服务引用,其中包含Reference.cs文件中包含的所有成员。

如果我包含我的FaultException合同,会发生两件事。

  1. 在WCF测试客户端中,合同名称旁边有一个红色的“X” (CreateFaultMessage)

  2. 当我创建WCF服务引用时, 并非所有成员都包含在Reference.cs文件中。

因为我不是WCF专家,所以我希望有人能够告诉我在创建FaultException合同时我做错了什么。

下面是我在合同中的代码声明。

[OperationContract] [FaultContractAttribute(typeof(LogEventArgs), ProtectionLevel = ProtectionLevel.None)] Exception CreateFaultMessage(Exception ex, string method); 

下面是实现接口的类中的方法。 注意在PostTransmissionRecord方法的catch块中调用CreateFaultMessage方法。

 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(detail); } 

更新的代码

DataContract类

 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; } } . . . 

服务方法抛出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; } } 

客户代码捕获故障记录

 catch (FaultException ex) { ex.Detail.ApplicationID = "ShopProcessService"; ex.Detail.LogEventType = LogEventTypeEnum.Error; serviceClient.Abort(); } 

为了简化从服务中抛出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 throw new FaultException("A fatal exception occurred while processing your request", new FaultCode("1000")) } } 

客户:

 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; } 

我相信这会解决你的问题。 🙂

请尝试将CustomFault(在此示例中为MathFault)定义为数据协定而不是操作合同,如:

 [DataContract] public class MathFault { //... } 

在客户端:

 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 e) { Console.WriteLine("FaultException: Math fault while doing " + e.Detail.Operation + ". Problem: " + e.Detail.ProblemType); client.Abort(); Console.ReadLine(); } } 

查看更多: 故障合同