2010-11-10 17 views
6

के दोष अपवादों को पकड़ने के लिए मैं सी # में बेस गलती अनुबंध प्रकार को पकड़ने के तरीके के बारे में जानने के लिए हर जगह देख रहा हूं। मैं अपने सभी गलती अनुबंधों को एक वर्ग से प्राप्त करना चाहता हूं और एमवीसी नियंत्रक में एक पकड़ (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> 
} 

कृपया मुझे तो हमें बताएं इनमें से किसी भी कैच स्टेटमेंट को मैं जो भी ढूंढ रहा हूं उसे करने के लिए तय किया जा सकता है।

उत्तर

2

क्षमा करें, ऐसा करने का कोई तरीका नहीं है। FaultException<T1> और FaultException<T2> के बीच कोई संबंध नहीं है क्योंकि T1T2 का उप-वर्ग हो सकता है।

+0

लेकिन इस व्यवहार का कारण क्या है? –

5

वह वाक्यविन्यास सी # में काम नहीं करेगा। इसके बजाए "कामकाज" पर विचार करें।

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 लेकिन निर्माण सामान्य प्रकार मैचों उपेक्षा सरल किया जा सकता। मैं थोड़ा और सरल बनाने के लिए सी # गतिशील कीवर्ड का भी उपयोग करूंगा।

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()) उपयोग करना चाहिए। फेंकने का यह तरीका आपको मूल रूप से प्रदान किए गए कोड का उपयोग करके पकड़ने देगा।

0

आपके क्लाइंट को message inspector की आवश्यकता है। हमारे पास एक समान situation था जहां सर्वर विभिन्न अपवाद फेंक रहा था और वे सभी एक FaultException के रूप में समाप्त हो गया।

संबंधित मुद्दे