Obiekt komunikacyjny System.ServiceModel.Channels.ServiceChannel nie może być używany do komunikacji, ponieważ znajduje się w stanie Faulted.
O co chodzi w tym błędzie i jak mam go rozwiązać?
Otrzymujesz ten błąd, ponieważ pozwoliłeś, aby wyjątek .NET wystąpił po stronie serwera, a nie został on przechwycony i obsłużony, ani też nie przekształcił go w błąd protokołu SOAP.
Odkąd strona serwera została „zbombardowana”, środowisko wykonawcze WCF „zepsuło” kanał - np. Łącze komunikacyjne między klientem a serwerem jest bezużyteczne - w końcu wygląda na to, że serwer właśnie się rozpalił, więc nie można się z nim komunikować to już więcej.
Musisz więc:
zawsze wychwytuj i obsługuj błędy po stronie serwera - nie pozwól, aby wyjątki .NET podróżowały z serwera do klienta - zawsze pakuj je w interoperacyjne błędy SOAP. Sprawdź interfejs WCF IErrorHandler i zaimplementuj go po stronie serwera
jeśli masz zamiar wysłać drugą wiadomość na swój kanał od klienta, upewnij się, że kanał nie jest w stanie błędu:
if(client.InnerChannel.State != System.ServiceModel.CommunicationState.Faulted)
{
// call service - everything's fine
}
else
{
// channel faulted - re-create your client and then try again
}
Jeśli tak, wszystko, co możesz zrobić, to zutylizować go i ponownie utworzyć serwer proxy po stronie klienta, a następnie spróbować ponownie
Aby zapobiec przechodzeniu serwera w stan błędu, należy upewnić się, że nie zostanie zgłoszony żaden nieobsługiwany wyjątek. Jeśli WCF widzi nieoczekiwany wyjątek, żadne więcej wywołań nie jest akceptowanych - najpierw bezpieczeństwo.
Dwie możliwości uniknięcia tego zachowania:
Użyj FaultException (ten nie jest nieoczekiwany dla WCF, więc WCF wie, że serwer ma nadal prawidłowy stan)
zamiast
używaj zawsze
być może możesz spróbować ... złapać cały blok i zgłosić FaultException we wszystkich przypadkach Exception
Powiedz WCF, aby obsłużył wszystkie wyjątki przy użyciu Errorhandler. Można to zrobić na kilka sposobów, wybrałem prosty, używając atrybutu:
wszystko, co musimy zrobić więcej, to użyć atrybutu
[SvcErrorHandlerBehaviour]
na żądanej implementacji usługiTo jest prosty przykład, możesz zagłębić się w IErrorhandler, nie używając nagiego
FaultException
, aleFaultException<>
z typem, który dostarcza dodatkowych informacji, zobacz IErrorHandler, aby uzyskać szczegółowy przykład.źródło
W rzeczywistości, jeśli nie powiedzie się po wykonaniu sugestii marc_s , należy pamiętać, że element <security> w konfiguracji powiązania serwera (lub jego brak) w web.config na serwerze może spowodować ten wyjątek. Na przykład serwer oczekuje
Message
poziomu bezpieczeństwa, a klient jest skonfigurowany na taki poziomNone
(lub, jeśli serwer nie jest częścią domeny Active Directory, ale zdalny host klienta jest).źródło
Aby zdiagnozować ten problem, uruchom usługę w debugerze programu Visual Studio. Użyj menu: Debugowanie | Wyjątki i wskaż, że chcesz przerwać, gdy zostanie zgłoszony wyjątek.
Oryginalny zgłoszony wyjątek będzie miał znacznie lepszy komunikat o błędzie niż „.. jest w stanie błędu”.
Na przykład otrzymałem ten wyjątek z ServiceHost.Open (), ale kiedy złapałem oryginalny wyjątek w momencie, gdy został zgłoszony, komunikat o błędzie brzmiał:
Naprawienie błędu pisowni w App.config rozwiązało problem.
źródło
Miałem ten sam problem podczas próby wykorzystania punktu końcowego usługi net.tcp wcf w usłudze http asmx.
Jak widziałem, nikt nie napisał konkretnej odpowiedzi DLACZEGO ten problem występuje, ale tylko jak należy go poprawnie rozwiązać.
Zmagałem się z tym kilka dni z rzędu i w końcu dowiedziałem się, skąd ten problem w moim przypadku.
Początkowo myślałem, że kiedy robisz odwołanie do usługi, plik konfiguracyjny zostanie skonfigurowany pod kątem tagu bezpieczeństwa w taki sam sposób, jak w źródle, ale tak nie było i powinienem zająć się tym ręcznie. W moim przypadku miałem tylko
Później zobaczyłem, że brakuje części zabezpieczającej i tak powinno wyglądać
Drugim problemem w moim przypadku było to, że korzystałem
transferMode="Streamed"
z mojej źródłowej usługi WCF, aw kliencie nie miałem nic konkretnego na ten temat, co było złe, ponieważ wartość domyślnatransferMode
toBuffered
i ważne jest, aby zarówno źródło, jak i klient były skonfigurowane w tym samym sposób.źródło
Miałem inny problem, o którym myślę, że nie został wspomniany w innych odpowiedziach.
Muszę obsługiwać punkty końcowe na tym samym adresie TCP i porcie. W pliku app.config zapomniałem dodać oba punkty końcowe, więc usługa działała na odpowiednim porcie, ale z niewłaściwym interfejsem usługi.
źródło
Jeśli zobaczysz ten komunikat w debugowaniu z programu Visual Studio, a rozwiązanie zawiera projekt WCF. Następnie otwórz te ustawienia projektu WCF -> przejdź do karty „Opcje WCF” -> wyłącz opcję „Uruchom hosta usługi WCF podczas debugowania ...”
źródło
U mnie problem był spowodowany przez plik konfiguracyjny automatycznie geneartowany przez import WSDL. Zaktualizowałem powiązanie z basicHttpBinding do customBinding. Dodanie dodatkowej obsługi wyjątków nie pomogło wskazać tego.
Przed
Po
źródło
W moim przypadku przyczyną był zły certyfikat, którego nie można było załadować. Dowiedziałem się o tym z Podglądu zdarzeń, pod System:
źródło
Ten błąd może być również wywołany przez Twój komputer, a nie tylko przez nieobsługiwany wyjątek. Jeśli Twój serwer / komputer ma zbyt wiele minut przesunięcia zegara, wiele usług internetowych .NET odrzuci Twoje żądanie z nieobsługiwanym błędem. Jest obsługiwany z ich punktu widzenia, ale nie jest obsługiwany z Twojego punktu. Sprawdź, czy czas na serwerze odbierającym jest prawidłowy. Jeśli trzeba to naprawić, musisz zresetować usługę lub uruchomić ponownie przed ponownym otwarciem kanału.
Wystąpił ten problem na serwerze, na którym zapora sieciowa blokowała aktualizację czasu w Internecie, a serwer z jakiegoś powodu przestał działać. Wszystkie zewnętrzne usługi internetowe .NET uległy awarii, ponieważ odrzucały każde żądanie usługi sieci Web. Przeglądanie przeglądarki zdarzeń pomogło zidentyfikować problem, ale dostosowanie zegara rozwiązało go. Błąd był po naszej stronie, mimo że otrzymaliśmy komunikat o błędzie stanu błędu dla przyszłych wezwań serwisu internetowego.
źródło
Serwer automatycznie przerwie połączenia, w których nie otrzymano żadnej wiadomości przez czas równy limitowi czasu odbioru ( domyślnie 10 minut ). Jest to zabezpieczenie przed atakiem DoS, aby zapobiec wymuszaniu przez klientów na serwerze otwierania połączeń przez nieokreślony czas.
Ponieważ serwer przerywa połączenie, ponieważ przeszedł w stan bezczynności, klient otrzymuje ten wyjątek.
Możesz kontrolować, jak długo serwer pozwala na bezczynne połączenie przed jego przerwaniem, konfigurując limit czasu odbioru w powiązaniu serwera. Źródło: TRVishwanath - MSFT
źródło
Wiem, że to starszy post, ale jedną rzeczą, na którą należy uważać, gdy nie możesz zmienić zabezpieczeń, jest upewnienie się, że Twoja nazwa użytkownika i hasło są ustawione.
Miałem usługę z authenticationMode jako UserNameOverTransport, gdy nazwa użytkownika i hasło nie były ustawione dla klienta usługi, otrzymywałbym ten błąd.
źródło
Dla mnie był to problem z równoważeniem obciążenia / adresem URL. Usługa WWW za równoważenia obciążenia nazywa inną usługę za tym samym równoważenia obciążenia przy użyciu pełnego adresu URL, takich jak:
loadbalancer.mycompany.com
. Zmieniłem to, aby ominąć moduł równoważenia obciążenia podczas wywoływania drugiej usługi, używająclocalhost.mycompany.com
zamiast tego.Myślę, że w module równoważenia obciążenia wystąpił jakiś problem z cyklicznymi odniesieniami.
źródło
Nie jest to rozwiązanie tego problemu, ale jeśli występuje powyższy błąd w Ektron eSync, może to oznaczać, że w bazie danych zabrakło miejsca na dysku.
Edycja: W rzeczywistości nie jest to wyłącznie problem dotyczący Ektron eSync. Może się to zdarzyć w przypadku każdej usługi wysyłającej zapytania do pełnej bazy danych.
Edycja: brak miejsca na dysku lub zablokowanie dostępu do katalogu, którego potrzebujesz, spowoduje ten problem.
źródło