c # WCF ловит Fault Исключения Базового типа - PullRequest
6 голосов
/ 10 ноября 2010

Я искал повсюду, чтобы узнать, как поймать базовый тип ошибки в c #.Я хотел бы, чтобы все мои контракты с ошибками наследовали от одного класса и имели один улов (FaultException fex) в контроллере MVC.

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>
}

Пожалуйста, дайте мне знать, можно ли исправить любой из этих операторов catch, чтобы выполнить то, что я ищудля.

Ответы [ 3 ]

5 голосов
/ 10 ноября 2010

Этот синтаксис не будет работать в 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()).Этот способ броска позволит вам ловить, используя код, который вы изначально предоставили.

2 голосов
/ 10 ноября 2010

Извините, нет способа сделать это. Между FaultException<T1> и FaultException<T2> нет никакой связи просто потому, что T1 может быть подклассом T2.

0 голосов
/ 11 ноября 2010

Вашему клиенту необходим инспектор сообщений . У нас была похожая ситуация , когда сервер выдавал различные исключения, и все они заканчивались как FaultException.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...