İletişim nesnesi, System.ServiceModel.Channels.ServiceChannel, iletişim için kullanılamaz


156

System.ServiceModel.Channels.ServiceChannel iletişim nesnesi, Faulted durumunda olduğu için iletişim için kullanılamaz.

Bu hata ne hakkında ve bu sorunu nasıl çözebilirim?

Yanıtlar:


151

Bu hatayı, sunucu tarafında bir .NET özel durumunun oluşmasına izin verdiğiniz ve yakalayıp işlemediğiniz ve bir SOAP hatasına dönüştürmediğiniz için alıyorsunuz.

Şimdi sunucu tarafı "bombalandı" beri, WCF çalışma zamanı kanalı "hatalı" - örneğin istemci ve sunucu arasındaki iletişim bağlantısı kullanılamaz - sonuçta, sunucunuzun sadece patladı gibi görünüyor, böylece iletişim kuramazsınız artık.

Yapmanız gereken şey:

  • Her zaman yakalamak ve sunucu tarafı hataları işlemek - yok - NET istisnalar sunucudan istemciye gezmesine izin daima birlikte çalışabilir SOAP hatalarına içine o sarın. WCF IErrorHandler arabirimini kontrol edin ve sunucu tarafında uygulayın

  • istemciden kanalınıza ikinci bir mesaj göndermek üzereyseniz, kanalın hatalı durumda olmadığından emin olun:

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

    Öyleyse, yapabileceğiniz tek şey elden çıkarmak ve istemci tarafı proxy'sini yeniden oluşturmak ve tekrar deneyin.


11
Sorun, istemci tarafında da olduğunda aynı hata ortaya çıkabilir: örneğin, gelen iletiler için ileti boyutu kotası aşıldığında.
svick

6
İstemciyi nasıl yeniden oluşturabilirim?
Mesud

32

Sunucunun Hata durumunda düşmesini önlemek için, işlenmeyen bir özel durum oluşmadığından emin olmalısınız. WCF beklenmedik bir İstisna görürse, daha fazla çağrı kabul edilmez - önce güvenlik.
Bu davranışı önlemek için iki olasılık:

  1. Bir FaultException kullanın (bu WCF için beklenmedik değildir, bu nedenle WCF sunucunun hala geçerli bir duruma sahip olduğunu bilir)
    yerine

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

    her zaman kullan

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

    belki tüm bloğu yakalayabilir ve bir İstisna durumunda tüm FaultException durumlarını deneyebilirsiniz.

    try   
    {  
        ... some code here   
    }
    catch (Exception ex)
    {  
        throw new FaultException(ex.Message)   
    }
  2. WCF'ye bir Hata İşleyicisi kullanarak tüm Özel Durumları işlemesini söyleyin. Bu birkaç şekilde yapılabilir, bir Özellik kullanarak basit bir tane seçtim:
    Daha fazlasını yapmamız gereken tek şey [SvcErrorHandlerBehaviour], istenen Hizmet Uygulamasındaki özelliği kullanmaktır.

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

Bu kolay bir örnektir, çıplak kullanmadan IErrorhandler'a daha derinlemesine dalabilirsiniz FaultException, ancak FaultException<>ek bilgi sağlayan bir türü olan ayrıntılı bir örnek için IErrorHandler'e bakın .


10

Nitekim, marc_s tarafından yapılan önerileri uyguladıktan sonra başarısız olursa, sunucudaki web.config dosyasındaki sunucu bağlama yapılandırmasındaki (veya eksikliğinden) <security> öğesinin bu özel duruma neden olabileceğini lütfen unutmayın. Örneğin sunucu Message-vel güvenlik bekler ve istemci şu şekilde yapılandırılır None(veya sunucu bir Active Directory etki alanının parçası değilse, ancak uzak istemci ana bilgisayarı ise).

İpucu: Bu gibi durumlarda, istemci uygulaması büyük olasılıkla RDP oturumunda yönetici hesabı altında doğrudan sunucu makinesinde yürütüldüğünde web hizmeti cezasını çağıracaktır.


2

Bu sorunu tanılamak için, hizmeti Visual Studio hata ayıklayıcı altında çalıştırın. Şu durumu kullanın: Hata ayıklama | İstisnalar ve bir İstisna atıldığında kırılmak istediğinizi belirtin.

Atılan orijinal istisna, ".. Hatalı durumda" ifadesinden çok daha iyi bir hata mesajına sahip olacaktır.

Örneğin bu istisnayı ServiceHost.Open () 'den alıyordum, ancak atıldığı sırada özgün özel durumu yakaladığımda hata iletisi:

'MyServiceName' hizmeti sıfır uygulama (altyapı dışı) uç noktaya sahip. Bunun nedeni, uygulamanız için hiçbir yapılandırma dosyasının bulunmaması veya yapılandırma dosyasında hizmet adıyla eşleşen bir hizmet öğesinin bulunamaması veya hizmet öğesinde hiçbir uç nokta tanımlanmamış olması olabilir.

App.config dosyasında yazım hatasını düzeltmek sorunu çözdü.


VS2015'te Hata Ayıkla → Özel Durum Ayarları'nı seçin ve Ortak Dil Çalışma Zamanı Özel Durumları'nı işaretleyin.
SharpC

1
Öyleyse neden Visual Studio hata ayıklayıcısını kullanana kadar orijinal istisna verilmedi?
Jez

2

Bir http asmx hizmetinde net.tcp wcf hizmeti uç noktasını tüketmeye çalışırken aynı sorunu yaşadım.

Gördüğüm gibi kimse neden belirli bir cevap yazmamıştı?

Birkaç gün üst üste bununla mücadele ediyorum ve sonunda sorunun benim durumumdan nereden geldiğini öğrendim.

Başlangıçta bir servise başvuru yaptığınızda, yapılandırma dosyasının güvenlik etiketiyle ilgili kaynakta olduğu gibi yapılandırılacağını düşündüm, ancak durum böyle değildi ve bu konuya manuel olarak bakmalıyım. Benim durumumda sadece

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

Daha sonra güvenlik bölümünün eksik olduğunu gördüm ve şöyle görünmeli

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

Benim durumumdaki ikinci sorun, transferMode="Streamed"kaynak WCF hizmetimde kullanıyordum ve istemcide bu konuda belirli bir şeyim yoktu, bu da kötüydü, çünkü varsayılan transferMode, Bufferedhem kaynak hem de istemcinin aynı şekilde yapılandırılması önemlidir yol.


1

Başka bir sorunum vardı, diğer cevaplarda zikredildiğini düşünmüyorum.

Aynı tcp adresinde ve bağlantı noktasında uç noktalara hizmet vermeliyim. App.config dosyasında, her iki uç noktasını da eklemeyi unutmuştum, bu nedenle hizmet doğru bağlantı noktasında çalışıyor, ancak yanlış hizmet arabirimiyle.


1

Visual Studio Debug'da bu iletiyi görürseniz ve çözüm WCF projesi içerir. Ardından bu WCF proje ayarlarını açın -> "WCF Seçenekleri" sekmesine gidin -> kapalı "Hata ayıklama sırasında WCF Service Host'u başlat ..." seçeneği


Aynı sorunu yaşadım ve bir süre bu konuda takılı kaldım. Muhtemelen hem istemci hem de sunucunun aynı çözümde bulunması iyi bir uygulama değildir. Teşekkür ederim!
yoosha

1

Benim için sorun, WSDL içe aktarılarak otomatik olarak oluşturulan yapılandırma dosyası nedeniyle oluştu. Bağlanma için basicHttpBinding customBinding güncellendi. Ek istisna işleme eklemek, bunu belirtmeye yardımcı olmadı.

Önce

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

Sonra

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

0

Benim durumumun nedeni yüklenemeyen yanlış bir sertifikaydı. Sistem altında Olay Görüntüleyicisi'nden öğrendim:

TLS sunucusu kimlik bilgileri özel anahtarına erişilmeye çalışılırken önemli bir hata oluştu. Şifreleme modülünden döndürülen hata kodu 0x8009030D'dir. Dahili hata durumu 10001'dir.


0

Bu hata, yalnızca işlenmeyen bir istisna değil, kendi bilgisayarınız tarafından da tetiklenebilir. Sunucunuzda / bilgisayarınızda saat süresi çok uzun sürerse, birçok .NET web hizmeti isteğinizi işlenmemiş bir hatayla reddeder. Onların bakış açısından ele alınır, ama sizin açınızdan ele alınmaz. Alıcı sunucunuzun saatinin doğru olduğundan emin olun. Düzeltilmesi gerekiyorsa, kanal yeniden açılmadan önce hizmetinizi sıfırlamanız veya yeniden başlatmanız gerekir.

Bu sorunu, güvenlik duvarının İnternet saati güncellemesini engellediği bir sunucuda yaşadım ve sunucunun bir nedenden dolayı zamanını kesti. Tüm üçüncü taraf .NET web hizmetleri, herhangi bir web hizmeti isteğini reddettiği için hata yaptı. Olay Görüntüleyicisi'ne girmek, sorunun belirlenmesine yardımcı oldu, ancak saati ayarlamak sorunu çözdü. Gelecekteki web hizmeti çağrıları için Arızalı Durum hata mesajı almamıza rağmen hata bizim tarafımızdaydı.


0

Sunucu, alma zaman aşımına eşit süre boyunca hiçbir mesaj alınmayan bağlantıları otomatik olarak iptal eder ( varsayılan 10 dakikadır) ). Bu, istemcilerin sunucuyu belirsiz bir süre boyunca bağlantılarını açık tutmaya zorlamalarını önlemek için bir DoS azaltımıdır.

Sunucu boşta kaldığı için bağlantıyı iptal ettiğinden, istemci bu özel durumu alır.

Sunucunun bağlayıcısındaki alma zaman aşımını yapılandırarak sunucunun iptal etmeden önce bir bağlantının ne kadar süre boşta kalmasına izin verdiğini denetleyebilirsiniz. Kredi bilgileri: TRVishwanath - MSFT


0

Bunun eski bir yazı olduğunu biliyorum, ancak güvenliği değiştiremediğinizde dikkat etmeniz gereken bir şey, kullanıcı adınızın ve şifrenizin ayarlandığından emin olmaktır.

UserNameOverTransport olarak authenticationMode ile bir hizmet vardı, hizmet istemcisi için kullanıcı adı ve parola ayarlanmadığında bu hatayı alırdım.


0

Benim için bir yük dengeleyici / url sorunu oldu. Bir yük dengeleyici arkasında bir web hizmeti gibi tam url kullanarak aynı yük dengeleyici başka bir hizmet olarak adlandırılır: loadbalancer.mycompany.com. Bunun localhost.mycompany.comyerine ikinci servisi çağırırken yük dengeleyiciyi atlayacak şekilde değiştirdim .

Yük dengeleyici ile ilgili bir tür dairesel referans sorunu olduğunu düşünüyorum.


-2

Bu sorunun çözümü değil, ancak Ektron eSync ile ilgili yukarıdaki hatayı yaşıyorsanız, veritabanınızda disk alanı kalmamış olabilir.

Edit: Aslında bu tamamen Ektron eSync sadece bir sorun değil. Bu, tam veritabanını sorgulayan herhangi bir hizmette olabilir.

Düzenleme: Disk alanı yetersiz veya ihtiyacınız olan bir dizine erişimi engellemek bu soruna neden olur.


Bu soruya bir cevap vermez. Bir yazarın eleştirisini yapmak veya açıklama istemek için yazılarının altına bir yorum bırakın - her zaman kendi yayınlarınıza yorum yapabilirsiniz ve yeterli bir üne sahip olduğunuzda herhangi bir yazı hakkında yorum yapabilirsiniz .
Dariusz

2
"Nasıl çözeceğim?" Sorusunu cevapladım, bu benim hatam değil, Ektron'u kullanıp kullanmadığına dair bize hiçbir zaman detay vermedi. Ayrıca yazısına yorum yapmak için 50 temsilciye ihtiyacım var.
Jonathan Bick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.