wcf的异常不会导致当前结束当前进程。客户端通过捕获System.ServiceModel.FaultException及其子类System.ServiceModel.FaultException<TDetail>来获得异常信息。在调试的时候可以设置includeExceptionDetailInFaults="true"获得异常详情。部署之后,要设置includeExceptionDetailInFaults="false"。客户端可以捕获System.ServiceModel.FaultException<TDetail>来得到异常信息。这里的TDetail可以是一个数据契约,这样客户端就可以看到TDetail的内容了。msdn给了例子:http://msdn.microsoft.com/en-us/library/ms576199(v=vs.90).aspx
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace Microsoft.WCF.Documentation
{
[ServiceContract(Namespace="http://microsoft.wcf.documentation")]
public interface ISampleService{
[OperationContract]
[FaultContractAttribute(
typeof(GreetingFault),
Action="http://www.contoso.com/GreetingFault",
ProtectionLevel=ProtectionLevel.EncryptAndSign
)]
string SampleMethod(string msg);
}
[DataContractAttribute]
public class GreetingFault
{
private string report;
public GreetingFault(string message)
{
this.report = message;
}
[DataMemberAttribute]
public string Message
{
get { return this.report; }
set { this.report = value; }
}
}
class SampleService : ISampleService
{
#region ISampleService Members
public string SampleMethod(string msg)
{
Console.WriteLine("Client said: " + msg);
// Generate intermittent error behavior.
Random rand = new Random(DateTime.Now.Millisecond);
int test = rand.Next(5);
if (test % 2 != 0)
return "The service greets you: " + msg;
else
throw new FaultException<GreetingFault>(new GreetingFault("A Greeting error occurred. You said: " + msg));
}
#endregion
}
}
要写FaultContractAttribute特性,如果没有该特性就不能捕获FaultException<GreetingFault>,只能捕获FaultException。客户端:
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;
public class Client
{
public static void Main()
{
// Picks up configuration from the config file.
SampleServiceClient wcfClient = new SampleServiceClient();
try
{
// Making calls.
Console.WriteLine("Enter the greeting to send: ");
string greeting = Console.ReadLine();
Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));
Console.WriteLine("Press ENTER to exit:");
Console.ReadLine();
// Done with service.
wcfClient.Close();
Console.WriteLine("Done!");
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException<GreetingFault> greetingFault)
{
Console.WriteLine(greetingFault.Detail.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException unknownFault)
{
Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
Console.ReadLine();
wcfClient.Abort();
}
}
}
但实际用的时候出异常了“The creator of this fault did not specify a Reason 此错误的创建者未指定“原因”
wcf要抛出FaultException时,原因是必须的,详情是可选的。所有必须要定义一个原因。可以这样:
throw new FaultException<GreetingFault>(new GreetingFault("A Greeting error occurred. You said: " + msg),"reason");
throw new FaultException<GreetingFault>(new GreetingFault("A Greeting error occurred. You said: " + msg), new FaultReason("reason"));
但是还有一个异常FaultException`1 was unhandled by user code。因为,要让client去捕获
网上给了解决办法:http://stackoverflow.com/questions/13044288/wcf-unhandled-faultexception-was-not-handled-by-usercode
Go to Debug -> Exceptions and uncheck the checkbox under Thrown column for row CLR exception.
If that checkbox is checked, it will cause the debugger to stop at every location where you are throwing exception.
或者用:http://social.technet.microsoft.com/wiki/contents/articles/17418.the-famous-system-servicemodel-faultexception1-was-unhandled-by-user-code.aspx