c#WCF捕获Base类型的故障异常

时间:2010-11-10 00:09:21

标签: c# wcf

我一直在寻找如何在c#中捕获基本错误契约类型。我希望我的所有错误契约都从一个类继承,并在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<Class2>(new Class2(), "Class2 Reason");
    }
}

服务消费者

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

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

3 个答案:

答案 0 :(得分:5)

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

try
{
    throw new FaultException<DerivedClass2>(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但构造的泛型类型匹配的异常情况,可以简化这一点。我还将使用C#动态关键字进一步简化它。

try
{
    throw new FaultException<DerivedClass2>(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<BaseClass1>(new DerivedClass2())。这种投掷方式可以让你使用最初提供的代码。

答案 1 :(得分:2)

抱歉,没有办法做到这一点。 FaultException<T1>FaultException<T2>之间没有任何关系,因为T1可能是T2的子类。

答案 2 :(得分:0)

您的客户需要message inspector。我们有一个类似的situation,其中服务器抛出各种异常,它们最终都是一个FaultException。