我正在测试WCF是否有可能实现一个API来远程控制在Windows上运行我们的控制器软件(C#/。Net 4.6.1)的设备。
我目前正在尝试弄清楚如何从我的服务中抛出并捕获FaultException
并从.Net客户端捕获它。
我遇到的问题是,在运行代码时(在VS 2015上的调试模式下),客户端没有捕获到异常,但VS最终在VS的代码位置显示异常。服务(Service.cs
),它被抛出的地方。异常消息是:
WcfService.dll中出现'System.ServiceModel.FaultException`1'类型的异常,但未在用户代码中处理
附加信息:参数值不是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.Reentrant,
InstanceContextMode = InstanceContextMode.Single)]
公共类服务:IService
{
私有字符串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
:
公共类服务器
{
私人ServiceHost svh;
私人服务;
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();
}
}
答案 0 :(得分:0)
如果使用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 :(得分:0)
我最近遇到了他的问题(如果我理解正确的话)
1)VS - &gt; DEBUG - &gt;选项和设置 - &gt;调试 - &gt;一般
当异常跨越AppDomain时,UNTICK&#39;中断...&#39;
2)DEBUG - &gt;异常并取消选择公共语言运行库的异常(Thrown和user-unhandled)并再次尝试。如果这样可以解决问题,您可以在AppDomain上测试异常时查找要自定义的异常,或者只执行此操作。
答案 2 :(得分:0)
确定。幸运的是,我找到了问题的答案。该错误是由于在Visual Studio中以调试模式运行我的代码,其中VS在抛出异常时捕获异常。为了使其正常工作,您需要禁用某些设置。要执行此操作,请转到Tools->Option->Debugging->General
并删除复选标记:
Enable the exception assistant
Enable just my code
我找到了这个解决方案here。