题
我在WCF服务中有以下代码,可以根据某些情况进行自定义故障。我得到的是“这个错误的创建者没有指定原因”例外。我究竟做错了什么?
//source code
if(!DidItPass)
{
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(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; }
}
}
解决方案
经过一些附加的研究,以下修改的代码有效:
if(!DidItPass)
{
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason("Invalid Routing Code - No Approval Started"));
}
其他提示
简短的答案是,您没有做错任何事情,只需错误地阅读结果即可。
在客户端捕获错误时,捕获的类型是 System.ServiceModel.FaultException<InvalidRoutingCodeFault>
.
您的 InvalidRoutingCodeFault
对象实际上在 .detail
FARSEXCEPTION的属性。所以....
//客户端代码
private static void InvokeMyMethod()
{
ServiceClient service = new MyService.ServiceClient();
try
{
service.MyMethod();
}
catch (System.ServiceModel.FaultException<InvalidRoutingCodeFault> ex)
{
// 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);
}
}
错误页面上显示的消息属性是错误页面上显示的内容,因此,如果它没有像John Egerton的帖子中填充,您将看到“此故障的创建者未指定原因”消息。为了轻松填充它,请在将故障扔在服务中时使用两个参数构造函数,从您的故障类型传递错误消息:
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(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<FormatFault>(fault);
}
}
// client calling code
private static void InvokeWCF2()
{
ServiceClient service = new ServiceClient();
try
{
service.DoWork2();
}
catch (FaultException<FormatFault> 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);
}
}
如果不需要故障原因,则无需添加故障原因。只需确保conalltract属性正确
我使用两个参数约束解决了这个问题。
// service method implementation
throw new FaultException<FormatFault>(fault,new FaultReason(fault.CustomFaultMassage));
CustomFaultMassage是数据合同中的属性。
如果一个人未指定该方法的FARSCONTRACT(typeof(className))属性,也可以遇到此异常
如果您不想被通知此类例外,请进行调试 - >异常,并为“通用语言运行时异常”或特定异常取消选中“用户不合适”。
我的代码与Rashmi一样,我得到了“这个故障的创建者……”错误。当我在VS2010进行调试时,这发生了。我找到了这篇文章:
这解释了我需要关闭的几个调试选项。问题解决了。
您可以在服务器配置(行为 - > servicebehaviors->行为)中尝试此操作:
<serviceDebug includeExceptionDetailInFaults="true" />
通过使用强烈键入的尝试捕获,我能够解决“此故障的创建者未指定原因”的错误。
更新客户端中的服务参考解决了问题。同样可以对您有用。