2012-01-06 15 views
14

मान लें कि हमारे पास एक सेवा विधि है जो कुछ सुरक्षा जांच करता है, डीबी और तृतीय पक्ष वेब सेवा से डेटा पुनर्प्राप्त करता है, MyDataDTO बनाता है, डीबी में एक लेखापरीक्षा प्रविष्टि लिखता है। और हम अच्छी तरह से संरचित, दानेदार त्रुटि कोड चाहते हैं, है ना? हम अच्छे लड़के हैं और मानक WCF त्रुटि हैंडलिंग के दिशा-निर्देशों का पालन करें:वास्तविक दुनिया में डब्ल्यूसीएफ गलती अनुबंध

[FaultContract(typeof(AccessDenied))] 
[FaultContract(typeof(KeyNotFound))] 
[FaultContract(typeof(WsFault))] 
[FaultContract(typeof(DbFault))] 
MyDataDTO GetData(string key); 

अब हम एक नई पद्धति डेटा अद्यतन करता है कि जोड़ रहे हैं। विधि GetData() आंतरिक रूप से (या इसका मुख्य हिस्सा) कहती है, प्रमाणीकरण निष्पादित करता है डेटा अपडेट करता है।

[FaultContract(typeof(InvalidState))] 
[FaultContract(typeof(DataNotValid))] 
[FaultContract(typeof(AccessDenied))] 
[FaultContract(typeof(KeyNotFound))] 
[FaultContract(typeof(WsFault))] 
[FaultContract(typeof(DbFault))] 
void UpdateData(MyDataDTO data); 

अब तक तो अच्छा: तो यह GetData() दोहराया के सभी दोष है प्लस अपने स्वयं के दोष को जोड़ना होगा। यह हमें XML उत्पन्न करने के लिए भी अनुमति देता है जो हम अपनी सेवा के उपभोक्ताओं के लिए प्रदान कर सकते हैं ताकि वे जान सकें कि वे कौन से त्रुटि कोड की उम्मीद कर सकते हैं।

अब कल्पना करें कि हमारे पास 10 विधियों के साथ 10 सेवाएं हैं (या इससे भी अधिक जटिल) प्रत्येक। और उन सभी गलती ठेके को परिभाषित हो जाता है इस के रूप में बुरा सपना काफी त्रुटि प्रवण प्रक्रिया है:

  1. आप गारंटी नहीं दे सकते कि एक गलती पर परिभाषित पूरे सेवा
  2. के लिए (DbFault) की तरह सामान्य दोष को परिभाषित करने का कोई तरीका नहीं है एक ऑपरेशन अनुबंध वास्तव में (कॉपी-पेस्ट मुद्दों)
  3. आप गारंटी नहीं दे सकते कि आप आपरेशन अनुबंध में जोड़ने के लिए कुछ गलती याद नहीं था लौटा दी जाएगी

यहाँ खाता इंटरफ़ेस संस्करण में नहीं लेते हैं :)

+०१२३५१६४१०६१

तो अगर आप उत्पादन में डब्ल्यूसीएफ सेवाओं का समर्थन करते हैं तो आपको तस्वीर मिल गई है। क्या हमें गलती अनुबंधों को छोड़ देना चाहिए और अच्छी पुरानी सी-शैली का उपयोग करना चाहिए (जैसे त्रुटि DTOBase कक्षा त्रुटि कोड के साथ)? त्रुटि ग्रैन्युलरिटी कम करें? यह सुनिश्चित करने के लिए कि दस्तावेज़ सही/अद्यतित है? मुझे कुछ बेहतरीन प्रथाओं में दिलचस्पी है।

+4

खुद से पूछने की एक बात यह है कि क्या आपके ग्राहक वास्तव में उन ग्रैनुलर त्रुटि कोड _using_ होंगे। क्या वे वास्तव में कौन सी गलती वापस आती हैं, या वे केवल त्रुटि संदेश प्रदर्शित करने के आधार पर अलग-अलग कार्रवाइयां कर रहे हैं? –

+0

अधिकतर प्रदर्शित। यह विभिन्न कार्यों के बजाय तेजी से समस्या निदान के लिए है। – UserControl

+4

फिर आपको केवल एक ही FaultContract की आवश्यकता है जिसमें 'संदेश' स्ट्रिंग है। –

उत्तर

1

ठीक है, तो आप इस लागू कर सकते हैं:

public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 

उस मामले में आप एक ही स्थान है, जहां आप/अपवाद प्रकार से स्विच करेंगे संदेश और स्वयं के दोष प्रदान करनी होगी।

http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.providefault.aspx

या नमूनों के साथ बेहतर अभी तक: अपने मूल दृष्टिकोण के साथ

http://blogs.msdn.com/b/pedram/archive/2008/01/25/wcf-error-handling-and-some-best-practices.aspx

+0

विल इस अद्यतन के साथ डबल्यूएसडीएल प्रत्येक ऑपरेशन द्वारा दोषों को वापस किया जाएगा? –

+0

@ जॉन सैंडर्स। नहीं, यह डब्लूएसडीएल अपडेट नहीं करेगा। –

9

एक समस्या यह है कि आप प्रणाली त्रुटियों/अपवाद है कि हो सकता है की भीड़ को दोहराने की कोशिश कर रहे है। चूंकि प्रत्येक नए फ़ंक्शन के साथ सिस्टम की जटिलता बढ़ जाती है, इसलिए संभावित समस्याओं की संख्या तेजी से बढ़ती है (या अधिक!)

मैं निम्न दृष्टिकोण का सुझाव दूंगा: चूंकि आप सेवाओं का "सिस्टम" बना रहे हैं और एक्सेस कॉल, केवल उस सिस्टम से संबंधित FaultContracts परिभाषित करें। ग्राहकों को केवल निम्नलिखित प्रश्नों में रुचि होनी चाहिए:

  1. क्या यह मुझे इच्छित डेटा के साथ एक समस्या है, या जिस तरीके से मैंने पूछा था?
  2. यदि नहीं, तो यह मेरे साथ एक समस्या है, या यह एक आईटी से संबंधित मुद्दा है (सिस्टम क्रैश, नेटवर्क त्रुटि, डेटाबेस समस्या, जो भी हो)?

थोड़ा सा कार्य करने के साथ, आप प्रदान करने वाले गलती अनुबंधों की संख्या में कटौती कर सकते हैं। उदाहरण (और यह मेरे सिर के ऊपर से है) के लिए:

//Base class to define general problems 
[DataContract] 
public class SysFault 
{ 
    //MyDataDTO-specific general error. 
    [DataMember] 
    public string SysMsg {get;set;} 

    //boolean for "this is a problem with me or the hosting system?" 
    [DataMember] 
    public bool IsSystemic {get;set;} 
} 

//Subclass to expose synchronization issues--if that's one you want to define 
[DataContract] 
public class SyncFault : SysFault 
{ 
    [DataMember] 
    public string SyncMsg { get;set; } 
} 

//Subclass to expose validation issues 
[DataContract] 
public class ValFault : SysFault 
{ 
    [DataMember] 
    public string ValMsg { get;set; } 
} 

अब, आप गलती प्रकार का उपयोग को अलग करने के क्या अपनी सेवाओं के साथ चल रहा है कर सकते हैं। उदाहरण के लिए:

[ServiceContract] 
public interface IRecordSys 
{ 
    [OperationContract] 
    [FaultContract(typeof(SysFault))] //Raised for underlying problem 
    [FaultContract(typeof(ValFault))] //Raised if there is an issue with the key value 
    MyDataDTO getData(string key); 

    [OperationContract] 
    [FaultContract(typeof(SysFault))] //Raised for underlying problem elsewhere 
    //Raised for some issue, such as unable to get two subsystems to update properly 
    //with the given data 
    [FaultContract(typeof(SyncFault))] 
    void update(MyDataDTO data); 
} 

आपका विशेष कार्यान्वयन अलग होगा, लेकिन यह विचार संदेशों पास किया जा सके कि चिंता का विषय अपने प्रणाली, नहीं हर छोटी प्रणालीगत समस्या यह है कि साथ आ सकता है।

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