c#WCF捕获Base类型的故障exception

我一直在寻找如何在c#中找到基本故障合同类型的方法。 我希望我的所有错误契约都从一个类inheritance并在MVC控制器中有一个catch(FaultException fex)。

DataContracts

[DataContract] public class BaseClass1 { } [DataContract] public class Class2 : BaseClass1 { } 

服务

 [ServiceContract] public interface IService1 { [OperationContract] [FaultContract(typeof(BaseClass1))] [FaultContract(typeof(Class2))] //Do I need this one? void ThrowClass2(); } public class Service1 : IService1 { public void ThrowClass2() { throw new FaultException(new Class2(), "Class2 Reason"); } } 

服务消费者

 FaultTestService.Service1Client client = null; try { client = new FaultTestService.Service1Client(); client.ThrowAmpFaults("InvalidParameter", 0); } catch (FaultException fex) { //DOES NOT GO IN HERE AS I WOULD EXPECT } catch (FaultException fex) { //Other Possible Option MessageFault fault = fex.CreateMessageFault(); var fe1 = fault.GetDetail(); //This throws a serialization exception it needs  } 

如果可以修复这些捕获语句中的任何一个来执行我正在寻找的内容,请告诉我。

该语法在C#中不起作用。 请考虑下面的“解决方法”。

 try { throw new FaultException(new DerivedClass2()); } catch (FaultException fex) { bool handled = false; Type fexType = fex.GetType(); if (fexType.IsGenericType && fexType.GetGenericTypeDefinition() == typeof(FaultException<>)) { if (typeof(BaseClass1).IsAssignableFrom(fexType.GetGenericArguments()[0])) { object detail = fexType.GetProperty("Detail").GetValue(fex, null); // Use detail here. handled = true; } } if (!handled) throw; // Don't know how to handle. Re-throw. } 

如果我们忽略Detail == null但构造的generics类型匹配的exception情况,这可以简化。 我还将使用C#动态关键字进一步简化它。

 try { throw new FaultException(new DerivedClass2()); } catch (FaultException fex) { bool handled = false; Type fexType = fex.GetType(); if (fexType.IsGenericType && fexType.GetGenericTypeDefinition() == typeof(FaultException<>)) { object detail = ((dynamic)fex).Detail; if (detail is BaseClass1) // true for subclasses too! { // Use detail here. } } if (!handled) throw; // Don't know how to handle. Re-throw. } 

另一件需要考虑的事情是你是否应该使用throw new FaultException(new DerivedClass2()) 。 这种投掷方式可以让您使用最初提供的代码。

对不起,没办法这样做。 FaultExceptionFaultException之间没有关系,因为T1可能是T2的子类。

您的客户需要一个消息检查器 。 我们有类似的情况 ,服务器抛出各种exception,它们都以FaultException结束。