如何在WCF中捕获自定义FaultException
本文关键字:自定义 FaultException WCF | 更新日期: 2023-09-27 18:05:57
我正在测试WCF是否有可能实现一个API,用于远程控制运行我们的控制器软件的设备(c#/。. Net 4.6.1)
我目前正试图找出如何抛出和捕获FaultException
从我的服务,并从。net客户端捕获它。
我遇到的问题是,当运行代码时(在VS 2015调试模式下),异常没有被客户端捕获,但VS最终向我展示了VS内部的异常,在服务的代码位置(Service.cs
),在那里它被抛出。异常消息为:
System.ServiceModel类型的异常。故障异常' 1'发生在WcfService.dll中,但未在用户代码中处理
附加信息:参数值不是1
其中The argument value was not 1
是我提供的自定义消息。下面是我代码的相关部分。我希望有人能指出我做错了什么:
IService.cs
:
[ServiceContract(CallbackContract = typeof(IMyEvents))]
public interface IService
{
[OperationContract]
[FaultContract(typeof(InvalidValueFault))]
string ThrowsFaultIfArgumentValueIsNotOne(int value);
...
}
[DataContract]
public class InvalidValueFault
{
private string _message;
public InvalidValueFault(string message)
{
_message = message;
}
[DataMember]
public string Message { get { return _message; } set { _message = value; } }
}
Service.cs
:[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.]可重入的,InstanceContextMode = InstanceContextMode. single)]公共类Service: IService{private string defaultString;
public Service(string ctorTestValue)
{
this.defaultString = ctorTestValue;
}
public string ThrowsFaultIfArgumentValueIsNotOne(int value)
{
if (value == 1)
return string.Format("Passed value was correct: {0}", value);
// this is where the box with the exception is shown inside Visual Studio
throw new FaultException<InvalidValueFault>(new InvalidValueFault("The argument value was not 1"), new FaultReason("The argument value was not 1"));
}
...
}
Server.cs
:公共类服务器{private ServiceHost svh;private Service Service;
public Server()
{
service = new Service("A fixed ctor test value that the service should return.");
svh = new ServiceHost(service);
}
public void Open(string ipAdress, string port)
{
svh.AddServiceEndpoint(
typeof(IService),
new NetTcpBinding(),
"net.tcp://"+ ipAdress + ":" + port);
svh.Open();
}
public void Close()
{
svh.Close();
}
}
Client.cs
:
public class Client : IMyEvents
{
ChannelFactory<IService> scf;
IService s;
public void OpenConnection(string ipAddress, string port)
{
var binding = new NetTcpBinding();
scf = new DuplexChannelFactory<IService>(
new InstanceContext(this),
binding,
"net.tcp://" + ipAddress + ":" + port);
s = scf.CreateChannel();
}
public void CloseConnection()
{
scf.Close();
}
public string ThrowsFaultIfArgumentValueIsNotOne(int value)
{
try
{
return s.ThrowsFaultIfArgumentValueIsNotOne(value);
}
catch (System.ServiceModel.FaultException<InvalidValueFault> fault)
{
Console.WriteLine("Exception thrown by ThrowsFaultIfArgumentValueIsNotOne(2):");
Console.WriteLine("Exception message: " + fault.Message);
//throw;
return "Exception happend.";
}
}
...
}
Program.cs
(使用服务器和客户端的测试程序):
class Program
{
static void Main(string[] args)
{
// start server
var server = new Server();
server.Open("localhost", "6700");
Console.WriteLine("Server started.");
var client = new Client();
client.OpenConnection("localhost", "6700");
Console.ReadLine();
Console.WriteLine("Result for client.ThrowsFaultIfArgumentValueIsNotOne(1): {0}", client.ThrowsFaultIfArgumentValueIsNotOne(1));
Console.ReadLine();
Console.WriteLine("Result for client.ThrowsFaultIfArgumentValueIsNotOne(2): {0}", client.ThrowsFaultIfArgumentValueIsNotOne(2));
Console.ReadLine();
client.CloseConnection();
Thread.Sleep(1000);
server.Close();
}
}
如果您使用vs tools从wsdl生成SOAP代码,那么这里抛出的FaultException是通用的FaultException -这意味着它是FaultException<fault_contract>
。您可以通过检查服务引用代码和检查[System.ServiceModel.FaultContractAttribute()]
属性来确定泛型异常。这个属性的Type参数是你的泛型类型。
如果它看起来像这样
[System.ServiceModel.FaultContractAttribute(typeof(MyFaultContract)]
[System.ServiceModel.OperationContractAttribute(Action = "SoapAction", ReplyAction = "*")]
SoapResponse SoapAction(SoapRequest request);
那么你的catch子句应该像这样
try {
soapClient.SoapAction(new SoapRequest());
}
catch (FaultException<MyFaultContract> e) {
}
我最近遇到了这个问题(如果我理解正确的话)
1) VS -> DEBUG -> Options and Settings -> Debugging -> General
There UNTICK 'Break when exceptions across AppDomain…'
2) DEBUG -> Exceptions并取消选择公共语言运行时(抛出和用户未处理)的异常,然后再试一次。如果这样可以解决问题,您可以查找想要自定义的异常,或者在跨AppDomain测试异常时这样做。
好的。我侥幸找到了问题的答案。错误是由于在Visual Studio的调试模式下运行我的代码,其中VS捕获异常抛出的那一刻。为了使其正常工作,您需要禁用一些设置。要做到这一点,请进入Tools->Option->Debugging->General
并删除复选标记:
-
Enable the exception assistant
-
Enable just my code
我在这里找到了这个解决方案