संचार ऑब्जेक्ट, System.ServiceModel.Channels.ServiceChannel, संचार के लिए उपयोग नहीं किया जा सकता है


156

संचार वस्तु, System.ServiceModel.Channels.ServiceChannel, संचार के लिए उपयोग नहीं किया जा सकता क्योंकि यह दोषपूर्ण स्थिति में है।

इस त्रुटि के बारे में क्या है, और मैं इसे कैसे हल करूंगा?

जवाबों:


151

आपको यह त्रुटि इसलिए मिलती है क्योंकि आपने अपने सर्वर साइड पर .NET अपवाद होने दिया, और आपने इसे नहीं पकड़ा और इसे हैंडल नहीं किया, और इसे SOAP गलती में भी परिवर्तित नहीं किया।

अब चूंकि सर्वर की ओर से "बमबारी" की गई है, डब्ल्यूसीएफ रनटाइम ने चैनल को "दोषपूर्ण" किया है - उदाहरण के लिए क्लाइंट और सर्वर के बीच संचार लिंक अनुपयोगी है - आखिरकार, ऐसा लगता है कि आपका सर्वर बस उड़ा दिया गया है, इसलिए आप इसके साथ संवाद नहीं कर सकते यह किसी भी अधिक है।

तो आपको क्या करने की आवश्यकता है:

  • हमेशा अपने सर्वर-साइड त्रुटियों को पकड़ें और संभालें - सर्वर से क्लाइंट के लिए .NET अपवादों को यात्रा न करने दें - हमेशा उन लोगों को इंटरऑपरेबल SOAP दोष में लपेटें। WCF IErrorHandler इंटरफ़ेस देखें और इसे सर्वर पर लागू करें

  • यदि आप क्लाइंट से अपने चैनल पर दूसरा संदेश भेजने वाले हैं, तो सुनिश्चित करें कि चैनल दोषपूर्ण स्थिति में नहीं है:

    if(client.InnerChannel.State != System.ServiceModel.CommunicationState.Faulted)
    {
       // call service - everything's fine
    }
    else
    {
       // channel faulted - re-create your client and then try again
    }

    यदि यह है, तो आप यह कर सकते हैं कि इसका निपटान कर दिया जाए और क्लाइंट साइड प्रॉक्सी को फिर से बनाया जाए और फिर से प्रयास करें


11
ऐसा लगता है कि एक ही त्रुटि तब हो सकती है जब समस्या क्लाइंट की ओर भी होती है: उदाहरण के लिए, जब आने वाले संदेशों के लिए संदेश आकार कोटा पार हो गया है।
svick

6
मैं ग्राहक को फिर से कैसे बना सकता हूं?
मसूद

32

सर्वर को फ़ॉल्ट स्थिति में गिरने से रोकने के लिए, आपको यह सुनिश्चित करना होगा कि कोई अखंडित अपवाद नहीं उठाया गया है। यदि WCF एक अप्रत्याशित अपवाद देखता है, तो कोई और कॉल स्वीकार नहीं की जाती है - पहले सुरक्षा।
इस व्यवहार से बचने के लिए दो कब्जे:

  1. FaultException का उपयोग करें (यह WCF के लिए अप्रत्याशित नहीं है, इसलिए WCF को पता है कि सर्वर के
    बजाय अभी भी एक वैध स्थिति है

    throw new Exception("Error xy in my function")  

    हमेशा उपयोग करें

    throw new FaultException("Error xy in my function")  

    शायद आप कोशिश कर सकते हैं..पूरे ब्लॉक को पकड़ें और अपवाद के सभी मामलों में एक FaultException को फेंक दें

    try   
    {  
        ... some code here   
    }
    catch (Exception ex)
    {  
        throw new FaultException(ex.Message)   
    }
  2. एक त्रुटिहेलर का उपयोग करके सभी अपवादों को संभालने के लिए WCF को बताएं। यह कई तरीकों से किया जा सकता है, मैंने एक साधारण का चयन किया है एक गुण का उपयोग करके:
    हम सभी को और अधिक करना है, [SvcErrorHandlerBehaviour]वांछित सेवा कार्यान्वयन पर विशेषता का उपयोग करना है

    using System;
    using System.Collections.ObjectModel;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher;
    
    namespace MainService.Services
    {
        /// <summary>
        /// Provides FaultExceptions for all Methods Calls of a Service that fails with an Exception
        /// </summary>
        public class SvcErrorHandlerBehaviourAttribute : Attribute, IServiceBehavior
        {
            public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            { } //implementation not needed
    
            public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
                                             BindingParameterCollection bindingParameters)
            { } //implementation not needed
    
            public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
                foreach (ChannelDispatcherBase chanDispBase in serviceHostBase.ChannelDispatchers)
                {
                    ChannelDispatcher channelDispatcher = chanDispBase as ChannelDispatcher;
                    if (channelDispatcher == null)
                        continue;
                    channelDispatcher.ErrorHandlers.Add(new SvcErrorHandler());
                }
            }
        }
    
        public class SvcErrorHandler: IErrorHandler
        {
            public bool HandleError(Exception error)
            {
                //You can log th message if you want.
                return true;
            }
    
            public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
            {
                if (error is FaultException)
                    return;
    
                FaultException faultException = new FaultException(error.Message);
                MessageFault messageFault = faultException.CreateMessageFault();
                msg = Message.CreateMessage(version, messageFault, faultException.Action);
            }
        }
    }

यह एक आसान उदाहरण है, आप नग्न का उपयोग नहीं करके IErrorhandler में गहराई से गोता लगा सकते हैं FaultException, लेकिन FaultException<>एक प्रकार के साथ जो अतिरिक्त जानकारी प्रदान करता है IERrorHandler को विस्तृत उदाहरण के लिए देखें।


10

तथ्य की बात के रूप में, अगर निम्नलिखित द्वारा सुझावों के बाद असफल marc_s , कृपया ध्यान रखें कि सर्वर पर सर्वर बाइंडिंग कॉन्फ़िगरेशन (या इसके अभाव) में web.config सर्वर में एक तत्व इस अपवाद का कारण हो सकता है। उदाहरण के लिए, सर्वर से Messageसुरक्षा की अपेक्षा की जाती है और क्लाइंट को कॉन्फ़िगर किया जाता है None(या, यदि सर्वर सक्रिय निर्देशिका डोमेन का हिस्सा नहीं है लेकिन दूरस्थ क्लाइंट होस्ट है)।

युक्ति: ऐसे मामलों में क्लाइंट ऐप आरडीपी सत्र में प्रशासनिक खाते के तहत सर्वर मशीन पर सीधे निष्पादित होने पर वेब सेवा को ठीक करने की संभावना करेगा।


2

इस समस्या का निदान करने के लिए, Visual Studio डीबगर के तहत सेवा चलाएँ। मेनू का उपयोग करें: डीबग करें। अपवाद और इंगित करें कि आप अपवाद को फेंकने के लिए तोड़ना चाहते हैं।

मूल अपवाद को फेंकने की स्थिति में ".. यह दोषपूर्ण स्थिति में है" की तुलना में बहुत बेहतर त्रुटि संदेश होगा।

उदाहरण के लिए मैं ServiceHost.Open () से यह अपवाद प्राप्त कर रहा था, लेकिन जब मैंने मूल अपवाद को पकड़ा था उस समय, त्रुटि संदेश था:

सेवा 'MyServiceName' में शून्य अनुप्रयोग (गैर-अवसंरचना) समापन बिंदु हैं। ऐसा इसलिए हो सकता है क्योंकि आपके एप्लिकेशन के लिए कोई कॉन्फ़िगरेशन फ़ाइल नहीं मिली, या क्योंकि सेवा नाम से मेल खाने वाला कोई सेवा तत्व कॉन्फ़िगरेशन फ़ाइल में नहीं मिल सकता है, या क्योंकि सेवा तत्व में कोई समापन बिंदु परिभाषित नहीं किए गए थे।

App.config में वर्तनी त्रुटि को ठीक करने से समस्या हल हो गई।


VS2015 में डिबग → एक्सेप्शन सेटिंग्स चुनें और कॉमन लैंग्वेज रनटाइम एक्सेप्शन पर टिक करें।
शार्प मार्क

1
तो जब तक आप Visual Studio डीबगर का उपयोग नहीं करते, तब तक मूल अपवाद क्यों नहीं दिया गया?
जेज

2

Http asmx सेवा में net.tcp wcf सर्विस एंडपॉइंट का उपभोग करने की कोशिश करते समय मुझे यही समस्या थी।

जैसा कि मैंने देखा कि कोई भी विशिष्ट उत्तर नहीं लिखता है कि यह समस्या क्यों हो रही है, लेकिन केवल कैसे ठीक से संभाला जाए।

मैं लगातार कई दिनों से इससे जूझ रहा था और आखिरकार मुझे पता चला कि मेरे मामले में समस्या कहाँ से आई है।

प्रारंभ में मैंने सोचा था कि जब आप किसी सेवा का संदर्भ लेते हैं तो सुरक्षा फ़ाइल उसी तरह से सुरक्षा टैग के बारे में कॉन्फ़िगर की जाएगी जैसे कि यह स्रोत में है, लेकिन यह मामला नहीं था और मुझे इसे ध्यान रखना चाहिए। मेरे मामले में मेरे पास केवल था

<netTcpBinding>
    <binding name="NetTcpBinding_IAuthenticationLoggerService"
    </binding>
</netTcpBinding>`

बाद में मैंने देखा कि सुरक्षा हिस्सा गायब है और इसे इस तरह दिखना चाहिए

<netTcpBinding>
    <binding name="NetTcpBinding_IAuthenticationLoggerService" transferMode="Buffered">
      <security mode="None">
        <transport clientCredentialType="None"/>
      </security>
    </binding>
  </netTcpBinding>

मेरे मामले में दूसरी समस्या यह थी कि मैं transferMode="Streamed"अपने स्रोत WCF सेवा पर उपयोग कर रहा था और क्लाइंट में मेरे पास इसके बारे में कुछ भी विशिष्ट नहीं था, जो कि खराब था, क्योंकि डिफ़ॉल्ट transferModeहै Bufferedऔर यह दोनों स्थानों और क्लाइंट पर समान रूप से कॉन्फ़िगर होने के लिए महत्वपूर्ण है। मार्ग।


1

मुझे एक और समस्या थी, कि मुझे नहीं लगता कि अन्य उत्तरों में इसका उल्लेख किया गया है।

मुझे उसी tcp एड्रेस और पोर्ट पर एंडपॉइंट सेवा करनी है। App.config में, मैं दोनों समापन बिंदुओं को जोड़ना भूल गया था, इसलिए सेवा सही पोर्ट पर चल रही थी, लेकिन गलत इंटरफ़ेस इंटरफ़ेस के साथ।


1

यदि आप Visual Studio से डीबग में यह संदेश देखते हैं और समाधान में WCF प्रोजेक्ट है। फिर इस WCF प्रोजेक्ट सेटिंग्स को खोलें -> "WCF ऑप्शंस" टैब पर जाएं - डिबगिंग के समय WCF सर्विस होस्ट शुरू करें ... "विकल्प


मुझे भी यही समस्या थी और इस मुद्दे पर काफी समय तक अटका रहा। संभवतः क्लाइंट और सर्वर दोनों का एक ही समाधान पर होना एक अच्छा अभ्यास नहीं है। धन्यवाद!
योशा

1

मेरे लिए यह समस्या WSDL को आयात करके स्वतः कॉन्फ़िगर की गई फ़ाइल के कारण हुई थी। मैंने BasicHttpBinding से कस्टमबाइंडिंग के लिए बाइंडिंग को अद्यतन किया। अतिरिक्त अपवाद हैंडलिंग को जोड़ने से यह इंगित करने में मदद नहीं मिली।

इससे पहले

<basicHttpBinding>
            <binding name="ServiceName">
                <security mode="Transport" />
            </binding>
        </basicHttpBinding>`

उपरांत

<customBinding>
        <binding name="ServiceName">
          <textMessageEncoding messageVersion="Soap12" />
          <httpsTransport />
        </binding>
      </customBinding>`

0

मेरे मामले में कारण कुछ गलत प्रमाणपत्र था जिसे लोड नहीं किया जा सकता था। मुझे सिस्टम के तहत इवेंट व्यूअर से इसके बारे में पता चला:

TLS सर्वर क्रेडेंशियल निजी कुंजी तक पहुँचने का प्रयास करते समय एक घातक त्रुटि हुई। क्रिप्टोग्राफिक मॉड्यूल से लौटाया गया त्रुटि कोड 0x8009030D है। आंतरिक त्रुटि स्थिति 10001 है।


0

इस त्रुटि को आपके स्वयं के कंप्यूटर द्वारा भी ट्रिगर किया जा सकता है, न कि केवल एक अनहेल्दी अपवाद। यदि आपके सर्वर / कंप्यूटर की घड़ी का समय बहुत अधिक मिनटों से बंद है, तो कई .NET वेब सेवाएं आपके अनुरोध को बिना किसी त्रुटि के अस्वीकार कर देंगी। यह उनके दृष्टिकोण से संभाला जाता है, लेकिन आपकी बात से बेपरवाह है। यह सुनिश्चित करने के लिए जांचें कि आपके प्राप्त सर्वर की घड़ी का समय सही है। यदि इसे ठीक करने की आवश्यकता है, तो आपको चैनल को फिर से खोलने से पहले अपनी सेवा को रीसेट करना होगा या रिबूट करना होगा।

मैंने इस समस्या को एक सर्वर पर अनुभव किया जहां फ़ायरवॉल ने इंटरनेट समय अद्यतन को अवरुद्ध कर दिया, और सर्वर किसी कारण से बंद हो गया। सभी तृतीय पक्ष .NET वेब सेवाएँ गलती से चली गईं क्योंकि उन्होंने किसी भी वेब सेवा अनुरोध को अस्वीकार कर दिया था। इवेंट व्यूअर में खुदाई करने से समस्या को पहचानने में मदद मिली, लेकिन घड़ी के समायोजन ने इसे हल कर दिया। त्रुटि तब भी हमारे अंत में थी, जब हमें भावी वेब सेवा कॉल के लिए दोषपूर्ण राज्य त्रुटि संदेश प्राप्त हुआ था।


0

सर्वर स्वचालित रूप से उन कनेक्शनों को निरस्त कर देगा जिन पर प्राप्त टाइमआउट के बराबर अवधि के लिए कोई संदेश नहीं मिला है ( डिफ़ॉल्ट 10 मिनट है )। यह एक डीईएस शमन है जो ग्राहकों को अनिश्चित समय के लिए सर्वर को खुले रखने के लिए मजबूर करने से रोकता है।

चूंकि सर्वर कनेक्शन को समाप्त कर देता है क्योंकि यह निष्क्रिय हो गया है, क्लाइंट को यह अपवाद मिलता है।

आप यह नियंत्रित कर सकते हैं कि सर्वर कब तक कनेक्शन को सर्वर के बाइंडिंग पर प्राप्त टाइमआउट को कॉन्फ़िगर करने से पहले निष्क्रिय करने की अनुमति देता है। साभार: TRVishwanath - MSFT


0

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन जब आप सुरक्षा नहीं बदल सकते हैं, तो यह देखने के लिए एक बात सुनिश्चित करें कि आपका उपयोगकर्ता नाम और पासवर्ड सेट है।

मेरे पास UserNameOverTransport के रूप में प्रमाणीकरणमोडे के साथ एक सेवा थी, जब सेवा क्लाइंट के लिए उपयोगकर्ता नाम और पासवर्ड सेट नहीं थे, तो मुझे यह त्रुटि मिलेगी।


0

मेरे लिए यह एक लोड बैलेंसर / यूआरएल मुद्दा था। एक लोड बैलेंसर के पीछे एक वेब सेवा उसी लोड बैलेंसर के पीछे एक और सेवा कहलाती है जैसे: पूर्ण url का उपयोग करना loadbalancer.mycompany.com। बदले में दूसरी सेवा को कॉल करते समय मैंने इसे लोड बैलेंसर को बायपास करने के लिए बदल दिया localhost.mycompany.com

मुझे लगता है कि लोड बैलेंसर के साथ किसी तरह का सर्कुलर रेफरेंस इश्यू चल रहा था।


-2

इस समस्या का समाधान नहीं है, लेकिन यदि आप एकट्रॉन eSync के साथ उपरोक्त त्रुटि का सामना कर रहे हैं, तो यह हो सकता है कि आपका डेटाबेस डिस्क स्थान से बाहर चला गया हो।

संपादित करें: वास्तव में यह पूरी तरह से एक एट्रॉन eSync केवल समस्या नहीं है। यह किसी भी सेवा पर हो सकता है जो एक पूर्ण डेटाबेस को क्वेरी कर रही है।

संपादित करें: डिस्क स्थान से बाहर निकलना, या उस निर्देशिका तक पहुंच को अवरुद्ध करना, जिसकी आपको आवश्यकता है, इस समस्या का कारण होगा।


यह प्रश्न का उत्तर प्रदान नहीं करता है। किसी लेखक से स्पष्टीकरण मांगने या उसका अनुरोध करने के लिए, उनकी पोस्ट के नीचे एक टिप्पणी छोड़ दें - आप हमेशा अपने स्वयं के पोस्ट पर टिप्पणी कर सकते हैं, और एक बार आपके पास पर्याप्त प्रतिष्ठा होने पर आप किसी भी पोस्ट पर टिप्पणी कर पाएंगे ।
दारिउज़

2
मैंने उनके सवाल का जवाब दिया "मैं इसे हल करने के बारे में कैसे जाऊंगा?", यह मेरी गलती नहीं है कि उसने हमें कभी इस बात पर विस्तार नहीं दिया कि वह एकट्रॉन का उपयोग कर रहा था या नहीं। मुझे उनकी पोस्ट पर टिप्पणी करने के लिए 50 प्रतिनिधि की भी आवश्यकता है।
जोनाथन बिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.