我在WCF服务中有以下代码,根据某些情况抛出自定义错误.我得到一个"这个错误的创建者没有指定原因"例外.我究竟做错了什么?
//source code if(!DidItPass) { InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started"); throw new FaultException(fault); } //operation contract [OperationContract] [FaultContract(typeof(InvalidRoutingCodeFault))] bool MyMethod(); //data contract [DataContract(Namespace="http://myuri.org/Simple")] public class InvalidRoutingCodeFault { private string m_ErrorMessage = string.Empty; public InvalidRoutingCodeFault(string message) { this.m_ErrorMessage = message; } [DataMember] public string ErrorMessage { get { return this.m_ErrorMessage; } set { this.m_ErrorMessage = value; } } }
Michael Knis.. 44
经过一些额外的研究,以下修改后的代码有效:
if(!DidItPass) { InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started"); throw new FaultException(fault, new FaultReason("Invalid Routing Code - No Approval Started")); }
Daniel Davis.. 17
简短的回答是你没有做错什么,只是错误地读取结果.
在客户端捕获错误时,捕获的是类型System.ServiceModel.FaultException
.
您的InvalidRoutingCodeFault
对象实际上.detail
是FaultException 的属性.所以....
//客户端代码
private static void InvokeMyMethod() { ServiceClient service = new MyService.ServiceClient(); try { service.MyMethod(); } catch (System.ServiceModel.FaultExceptionex) { // This will output the "Message" property of the System.ServiceModel.FaultException // 'The creator of this fault did not specify a Reason' if not specified when thrown Console.WriteLine("faultException Message: " + ex.Message); // This will output the ErrorMessage property of your InvalidRoutingCodeFault type Console.WriteLine("InvalidRoutingCodeFault Message: " + ex.Detail.ErrorMessage); } }
FaultException的Message属性是错误页面上显示的内容,因此如果它没有像John Egerton的帖子那样填充,您将看到"此错误的创建者未指定原因"消息.要轻松填充它,请在服务中抛出错误时使用两个参数构造函数,如下所示,从您的错误类型传递错误消息:
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started"); throw new FaultException(fault, new FaultReason(fault.ErrorMessage));
Rashmi Pandi.. 8
serviceDebug includeExceptionDetailInFaults="true"
不是解决方案
以下代码甚至可以使用 serviceDebug includeExceptionDetailInFaults="false"
// data contract [DataContract] public class FormatFault { private string additionalDetails; [DataMember] public string AdditionalDetails { get { return additionalDetails; } set { additionalDetails = value; } } } // interface method declaration [OperationContract] [FaultContract(typeof(FormatFault))] void DoWork2(); // service method implementation public void DoWork2() { try { int i = int.Parse("Abcd"); } catch (FormatException ex) { FormatFault fault = new FormatFault(); fault.AdditionalDetails = ex.Message; throw new FaultException(fault); } } // client calling code private static void InvokeWCF2() { ServiceClient service = new ServiceClient(); try { service.DoWork2(); } catch (FaultException e) { // This is a strongly typed try catch instead of the weakly typed where we need to do -- if (e.Code.Name == "Format_Error") Console.WriteLine("Handling format exception: " + e.Detail.AdditionalDetails); } }
如果不需要,则无需添加故障原因.只需确保FaultContract属性正确即可
经过一些额外的研究,以下修改后的代码有效:
if(!DidItPass) { InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started"); throw new FaultException(fault, new FaultReason("Invalid Routing Code - No Approval Started")); }
简短的回答是你没有做错什么,只是错误地读取结果.
在客户端捕获错误时,捕获的是类型System.ServiceModel.FaultException
.
您的InvalidRoutingCodeFault
对象实际上.detail
是FaultException 的属性.所以....
//客户端代码
private static void InvokeMyMethod() { ServiceClient service = new MyService.ServiceClient(); try { service.MyMethod(); } catch (System.ServiceModel.FaultExceptionex) { // This will output the "Message" property of the System.ServiceModel.FaultException // 'The creator of this fault did not specify a Reason' if not specified when thrown Console.WriteLine("faultException Message: " + ex.Message); // This will output the ErrorMessage property of your InvalidRoutingCodeFault type Console.WriteLine("InvalidRoutingCodeFault Message: " + ex.Detail.ErrorMessage); } }
FaultException的Message属性是错误页面上显示的内容,因此如果它没有像John Egerton的帖子那样填充,您将看到"此错误的创建者未指定原因"消息.要轻松填充它,请在服务中抛出错误时使用两个参数构造函数,如下所示,从您的错误类型传递错误消息:
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started"); throw new FaultException(fault, new FaultReason(fault.ErrorMessage));
serviceDebug includeExceptionDetailInFaults="true"
不是解决方案
以下代码甚至可以使用 serviceDebug includeExceptionDetailInFaults="false"
// data contract [DataContract] public class FormatFault { private string additionalDetails; [DataMember] public string AdditionalDetails { get { return additionalDetails; } set { additionalDetails = value; } } } // interface method declaration [OperationContract] [FaultContract(typeof(FormatFault))] void DoWork2(); // service method implementation public void DoWork2() { try { int i = int.Parse("Abcd"); } catch (FormatException ex) { FormatFault fault = new FormatFault(); fault.AdditionalDetails = ex.Message; throw new FaultException(fault); } } // client calling code private static void InvokeWCF2() { ServiceClient service = new ServiceClient(); try { service.DoWork2(); } catch (FaultException e) { // This is a strongly typed try catch instead of the weakly typed where we need to do -- if (e.Code.Name == "Format_Error") Console.WriteLine("Handling format exception: " + e.Detail.AdditionalDetails); } }
如果不需要,则无需添加故障原因.只需确保FaultContract属性正确即可
我使用两个参数构造函数解决了这个问题.
// service method implementation throw new FaultException(fault,new FaultReason(fault.CustomFaultMassage));
CustomFaultMassage是数据合同的属性.