Udostępnij za pośrednictwem


Szybki start: rozwiązywanie problemów z architekturą WCF

W tym temacie wymieniono szereg znanych problemów, które klienci napotkali podczas opracowywania klientów i usług WCF. Jeśli problem, w którym się znajdujesz, nie znajduje się na tej liście, zalecamy skonfigurowanie śledzenia dla usługi. Spowoduje to wygenerowanie pliku śledzenia, który można wyświetlić za pomocą przeglądarki plików śledzenia i uzyskać szczegółowe informacje o wyjątkach, które mogą występować w usłudze. Aby uzyskać więcej informacji na temat konfigurowania śledzenia, zobacz: Konfigurowanie śledzenia. Aby uzyskać więcej informacji na temat przeglądarki plików śledzenia, zobacz: Service Trace Viewer Tool (SvcTraceViewer.exe).

  1. Po zainstalowaniu systemu Windows 7 i usług IIS podczas próby przeglądania usługi WCF pojawia się następujący komunikat o błędzie: Błąd HTTP 404.3 — Nie znaleziono

    Błąd HTTP 404.3 — nie znalezionoStrona żądana nie może być obsługiwana z powodu konfiguracji rozszerzenia. Jeśli strona jest skryptem, dodaj procedurę obsługi. Jeśli plik powinien zostać pobrany, dodaj mapę MIME. Szczegółowe informacje o błędzieModule StaticFileModule.

  2. Czasami otrzymuję komunikat MessageSecurityException w drugim żądaniu, jeśli mój klient jest bezczynny przez pewien czas po pierwszym żądaniu. Co się dzieje?

  3. Moja usługa zaczyna odrzucać nowych klientów po tym, jak około 10 klientów wchodzi z nim w interakcję. Co się dzieje?

  4. Czy mogę załadować konfigurację usługi z innego miejsca niż plik konfiguracji aplikacji WCF?

  5. Moja usługa i klient działają świetnie, ale nie mogę dostać ich do pracy, gdy klient jest na innym komputerze? Co się dzieje?

  6. Gdy zgłaszam wyjątek> FaultException, w którym typ jest wyjątkiem, zawsze otrzymuję ogólny typ FaultException<na kliencie, a nie typ ogólny. Co się dzieje?

  7. Wygląda na to, że operacje jednokierunkowe i odpowiedzi na żądanie zwracają mniej więcej taką samą szybkość, gdy odpowiedź nie zawiera żadnych danych. Co się dzieje?

  8. Używam certyfikatu X.509 z moją usługą i otrzymuję wyjątek System.Security.Cryptography.CryptographicException. Co się dzieje?

  9. Zmieniłem pierwszy parametr operacji z wielkich liter na małe litery; teraz mój klient zgłasza wyjątek. Co się dzieje?

  10. Używam jednego z moich narzędzi do śledzenia i otrzymuję wyjątek EndpointNotFoundException. Co się dzieje?

  11. Podczas wywoływania internetowej aplikacji HTTP programu WCF z aplikacji protokołu SOAP WCF usługa zwraca następujący błąd: 405 Metoda niedozwolona

Jaki jest adres podstawowy? Jak odnosi się on do adresu punktu końcowego?

Po zainstalowaniu systemu Windows 7 i usług IIS podczas próby przeglądania usługi WCF pojawia się następujący komunikat o błędzie: Błąd HTTP 404.3 — Nie znaleziono

Pełny komunikat o błędzie to:

Błąd HTTP 404.3 — nie znalezionoStrona żądana nie może być obsługiwana z powodu konfiguracji rozszerzenia. Jeśli strona jest skryptem, dodaj procedurę obsługi. Jeśli plik powinien zostać pobrany, dodaj mapę MIME. Szczegółowe informacje o błędzieModule StaticFileModule.

Ten komunikat o błędzie występuje, gdy "Aktywacja HTTP programu Windows Communication Foundation" nie jest jawnie ustawiona w Panel sterowania. Aby ustawić tę opcję, przejdź do Panel sterowania, kliknij pozycję Programy w lewym dolnym rogu okna. Kliknij pozycję Włącz lub wyłącz funkcje systemu Windows. Rozwiń węzeł Microsoft .NET Framework 3.5.1 i wybierz pozycję Aktywacja HTTP programu Windows Communication Foundation.

Czasami otrzymuję komunikat MessageSecurityException w drugim żądaniu, jeśli mój klient jest bezczynny przez pewien czas po pierwszym żądaniu. Co się dzieje?

Drugie żądanie może zakończyć się niepowodzeniem głównie z dwóch powodów: (1) upłynął limit czasu sesji lub (2) serwer sieci Web hostujący usługę jest odzyskiwanych. W pierwszym przypadku sesja jest prawidłowa do czasu upłynął limit czasu usługi. Gdy usługa nie odbiera żądania od klienta w okresie określonym w powiązaniu usługi (ReceiveTimeout), usługa kończy sesję zabezpieczeń. Kolejne komunikaty klienta powodują wyświetlenie polecenia MessageSecurityException. Klient musi ponownie ustanowić bezpieczną sesję z usługą, aby wysyłać przyszłe komunikaty lub używać stanowego tokenu kontekstu zabezpieczeń. Stanowe tokeny kontekstu zabezpieczeń umożliwiają również bezpieczną sesję, aby przetrwać ponowne przetworzenie serwera sieci Web. Aby uzyskać więcej informacji na temat używania stanowych tokenów kontekstu bezpiecznego w bezpiecznej sesji, zobacz Instrukcje: tworzenie tokenu kontekstu zabezpieczeń na potrzeby bezpiecznej sesji. Alternatywnie można wyłączyć bezpieczne sesje. Jeśli używasz <powiązania wsHttpBinding> , możesz ustawić establishSecurityContext właściwość na wartość , aby false wyłączyć bezpieczne sesje. Aby wyłączyć bezpieczne sesje dla innych powiązań, należy utworzyć powiązanie niestandardowe. Aby uzyskać szczegółowe informacje na temat tworzenia powiązania niestandardowego, zobacz How to: Create a Custom Binding Using the SecurityBindingElement (Instrukcje: tworzenie powiązania niestandardowego przy użyciu elementu SecurityBindingElement). Przed zastosowaniem dowolnej z tych opcji należy zrozumieć wymagania dotyczące zabezpieczeń aplikacji.

Moja usługa zaczyna odrzucać nowych klientów po tym, jak około 10 klientów wchodzi z nim w interakcję. Co się dzieje?

Domyślnie usługi mogą mieć tylko 10 współbieżnych sesji. W związku z tym jeśli powiązania usługi używają sesji, usługa akceptuje nowe połączenia klienckie, dopóki nie osiągnie tej liczby, po czym odmówi nowych połączeń klienta do momentu zakończenia jednej z bieżących sesji. Więcej klientów można obsługiwać na wiele sposobów. Jeśli usługa nie wymaga sesji, nie używaj powiązania sesji. (Aby uzyskać więcej informacji, zobacz Korzystanie z sesji). Inną opcją jest zwiększenie limitu sesji przez zmianę wartości MaxConcurrentSessions właściwości na liczbę odpowiednią dla danej okoliczności.

Czy mogę załadować konfigurację usługi z innego miejsca niż plik konfiguracji aplikacji WCF?

Tak, należy jednak utworzyć klasę niestandardową ServiceHost , która zastępuje metodę ApplyConfiguration . Wewnątrz tej metody można najpierw wywołać bazę, aby załadować konfigurację (jeśli chcesz załadować standardowe informacje o konfiguracji), ale można również całkowicie zastąpić system ładowania konfiguracji. Jeśli chcesz załadować konfigurację z pliku konfiguracji innego niż plik konfiguracji aplikacji, musisz samodzielnie przeanalizować plik konfiguracji i załadować konfigurację.

Poniższy przykład kodu pokazuje, jak zastąpić metodę ApplyConfiguration i bezpośrednio skonfigurować punkt końcowy.

public class MyServiceHost : ServiceHost  
{  
    public MyServiceHost(Type serviceType, params Uri[] baseAddresses)
      : base(serviceType, baseAddresses)  
    {
        Console.WriteLine("MyServiceHost Constructor");
    }  
  
    protected override void ApplyConfiguration()  
    {  
        string straddress = GetAddress();  
        Uri address = new Uri(straddress);  
        Binding binding = GetBinding();  
        base.AddServiceEndpoint(typeof(IData), binding, address);  
    }  
  
    string GetAddress()  
    {
        return "http://MyMachine:7777/MyEndpointAddress/";
    }  
  
    Binding GetBinding()  
    {  
        WSHttpBinding binding = new WSHttpBinding();  
        binding.Security.Mode = SecurityMode.None;  
        return binding;  
    }  
}  

Moja usługa i klient działają świetnie, ale nie mogę dostać ich do pracy, gdy klient jest na innym komputerze? Co się dzieje?

W zależności od wyjątku może wystąpić kilka problemów:

  • Może być konieczne zmianę adresów punktów końcowych klienta na nazwę hosta, a nie na "localhost".

  • Może być konieczne otwarcie portu w aplikacji. Aby uzyskać szczegółowe informacje, zobacz Instrukcje zapory z przykładów zestawu SDK.

  • Aby uzyskać informacje o innych możliwych problemach, zobacz temat Przykłady dotyczące uruchamiania przykładów programu Windows Communication Foundation.

  • Jeśli klient używa poświadczeń systemu Windows, a wyjątek to SecurityNegotiationException, skonfiguruj protokół Kerberos w następujący sposób.

    1. Dodaj poświadczenia tożsamości do elementu punktu końcowego w pliku App.config klienta:

      <endpoint
        address="http://MyServer:8000/MyService/"
        binding="wsHttpBinding"
        bindingConfiguration="WSHttpBinding_IServiceExample"
        contract="IServiceExample"
        behaviorConfiguration="ClientCredBehavior"
        name="WSHttpBinding_IServiceExample">  
        <identity>  
          <userPrincipalName value="name@corp.contoso.com"/>  
        </identity>  
      </endpoint>  
      
    2. Uruchom usługę self-hosted na koncie System lub NetworkService. To polecenie można uruchomić, aby utworzyć okno polecenia w ramach konta systemowego:

      at 12:36 /interactive "cmd.exe"  
      
    3. Hostuj usługę w obszarze Internet Information Services (IIS), która domyślnie używa konta głównej nazwy usługi (SPN).

    4. Zarejestruj nową nazwę SPN w domenie przy użyciu programu SetSPN. Aby to zrobić, musisz być administratorem domeny.

Aby uzyskać więcej informacji na temat protokołu Kerberos, zobacz Pojęcia dotyczące zabezpieczeń używane w programie WCF i:

Gdy zgłaszam wyjątek> FaultException, w którym typ jest wyjątkiem, zawsze otrzymuję ogólny typ FaultException<na kliencie, a nie typ ogólny. Co się dzieje?

Zdecydowanie zaleca się utworzenie własnego niestandardowego typu danych o błędzie i zadeklarowanie, że jako typ szczegółów kontraktu błędów. Przyczyną jest użycie typów wyjątków dostarczonych przez system:

  • Tworzy zależność typu, która usuwa jedną z największych zalet aplikacji zorientowanych na usługi.

  • Nie można zależeć od wyjątków serializacji w standardowy sposób. Niektóre — na przykład SecurityException— mogą nie być serializowalne w ogóle.

  • Uwidacznia szczegóły implementacji wewnętrznej klientom. Aby uzyskać więcej informacji, zobacz Określanie i obsługa błędów w kontraktach i usługach.

Jeśli jednak debugujesz aplikację, możesz serializować informacje o wyjątkach i zwracać je do klienta przy użyciu ServiceDebugBehavior klasy .

Wygląda na to, że operacje jednokierunkowe i odpowiedzi na żądanie zwracają mniej więcej taką samą szybkość, gdy odpowiedź nie zawiera żadnych danych. Co się dzieje?

Określenie, że operacja jest jednym ze sposobów oznacza tylko, że kontrakt operacji akceptuje komunikat wejściowy i nie zwraca komunikatu wyjściowego. W programie WCF wszystkie wywołania klienta zwracają dane wychodzące do przewodu lub zgłaszany jest wyjątek. Operacje jednokierunkowe działają w taki sam sposób i mogą zgłaszać, jeśli usługa nie może być zlokalizowana lub zablokowana, jeśli usługa nie jest przygotowana do akceptowania danych z sieci. Zazwyczaj w programie WCF powoduje to, że jednokierunkowe wywołania zwracają się do klienta szybciej niż żądanie-odpowiedź; ale każdy warunek, który spowalnia wysyłanie danych wychodzących przez sieć spowalnia operacje jednokierunkowe, a także operacje żądania-odpowiedź. Aby uzyskać więcej informacji, zobacz Usługi jednokierunkowe i uzyskiwanie dostępu do usług przy użyciu klienta WCF.

Używam certyfikatu X.509 z moją usługą i otrzymuję wyjątek System.Security.Cryptography.CryptographicException. Co się dzieje?

Dzieje się tak często po zmianie konta użytkownika, w ramach którego jest uruchamiany proces roboczy usług IIS. Na przykład w systemie Windows XP, jeśli zmienisz domyślne konto użytkownika, w ramach którego Aspnet_wp.exe działa z platformy ASPNET na niestandardowe konto użytkownika, może zostać wyświetlony ten błąd. W przypadku korzystania z klucza prywatnego proces, który go używa, będzie musiał mieć uprawnienia dostępu do pliku przechowującego ten klucz.

W takim przypadku musisz przyznać uprawnienia dostępu do odczytu do konta procesu dla pliku zawierającego klucz prywatny. Jeśli na przykład proces roboczy usług IIS jest uruchomiony w ramach konta Boba, musisz przyznać Bobowi dostęp do odczytu do pliku zawierającego klucz prywatny.

Aby uzyskać więcej informacji o sposobie udzielenia poprawnego dostępu do pliku zawierającego klucz prywatny dla określonego certyfikatu X.509, zobacz How to: Make X.509 Certificates Accessible to WCF (Instrukcje: udostępnianie certyfikatów X.509 w programie WCF).

Zmieniłem pierwszy parametr operacji z wielkich liter na małe litery; teraz mój klient zgłasza wyjątek. Co się dzieje?

Wartości nazw parametrów w podpisie operacji są częścią kontraktu i są uwzględniane wielkość liter. Użyj atrybutu System.ServiceModel.MessageParameterAttribute , jeśli musisz odróżnić nazwę parametru lokalnego od metadanych opisujących operację dla aplikacji klienckich.

Używam jednego z moich narzędzi do śledzenia i otrzymuję wyjątek EndpointNotFoundException. Co się dzieje?

Jeśli używasz narzędzia do śledzenia, które nie jest mechanizmem śledzenia WCF dostarczonego przez system i otrzymujesz komunikat EndpointNotFoundException wskazujący, że wystąpiła niezgodność filtru adresów, należy użyć ClientViaBehavior klasy , aby skierować komunikaty do narzędzia śledzenia i mieć narzędzie przekierowujące te komunikaty do adresu usługi. Klasa ClientViaBehavior zmienia Via nagłówek adresowania w celu określenia następnego adresu sieciowego oddzielnie od końcowego odbiornika wskazanego To przez nagłówek adresowania. W takim przypadku nie należy jednak zmieniać adresu punktu końcowego, który jest używany do ustanowienia To wartości.

Poniższy przykładowy kod przedstawia przykładowy plik konfiguracji klienta.

<endpoint
  address="http://localhost:8000/MyServer/"  
  binding="wsHttpBinding"  
  bindingConfiguration="WSHttpBinding_IMyContract"  
  behaviorConfiguration="MyClient"
  contract="IMyContract"
  name="WSHttpBinding_IMyContract">  
</endpoint>  
<behaviors>  
  <endpointBehaviors>  
    <behavior name="MyClient">  
      <clientVia viaUri="http://localhost:8001/MyServer/"/>  
    </behavior>  
  </endpointBehaviors>  
</behaviors>  

Jaki jest adres podstawowy? Jak odnosi się on do adresu punktu końcowego?

Adres podstawowy to adres ServiceHost główny klasy. Domyślnie, jeśli dodasz klasę ServiceMetadataBehavior do konfiguracji usługi, język opisu usług sieci Web (WSDL) dla wszystkich punktów końcowych publikowanych przez hosta są pobierane z adresu podstawowego HTTP, a także wszelkie adresy względne podane do zachowania metadanych oraz "?wsdl". Jeśli znasz ASP.NET i usługi IIS, adres podstawowy jest odpowiednikiem katalogu wirtualnego.

Udostępnianie portu między punktem końcowym usługi a punktem końcowym mex przy użyciu narzędzia NetTcpBinding

Jeśli określisz podstawowy adres usługi jako net.tcp://MyServer:8080/MyService i dodaj następujące punkty końcowe:

<services>  
  <service name="Microsoft.Samples.NetTcp.CalculatorService">  
    <endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>  
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />  
  </service>  
</services>  

Jeśli zmodyfikujesz jedno z ustawień NetTcpBinding, jak pokazano w poniższym fragmencie konfiguracji:

<bindings>  
  <netTcpBinding>  
    <binding closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="11" maxReceivedMessageSize="65536">  
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>  
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>  
      <security mode="Transport">  
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>  
      </security>  
    </binding>  
  </netTcpBinding>  
</bindings>  

Zostanie wyświetlony błąd podobny do następującego: Nieobsługiwany wyjątek: System.ServiceModel.AddressAlreadyInUseException: W punkcie końcowym IP 0.0.0.0.0.0.9000 Można obejść ten błąd, określając w pełni kwalifikowany adres URL z innym portem punktu końcowego MEX, jak pokazano w poniższym fragmencie konfiguracji:

<services>  
  <service name="Microsoft.Samples.NetTcp.CalculatorService">  
    <endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>  
    <endpoint address="net.tcp://localhost:9001/servicemodelsamples/mex" binding="mexTcpBinding" contract="IMetadataExchange" />  
  </service>  
</services>  

Podczas wywoływania internetowej aplikacji HTTP programu WCF z aplikacji protokołu SOAP WCF usługa zwraca następujący błąd: 405 Metoda niedozwolona

Wywołanie aplikacji HTTP sieci Web programu WCF (usługi korzystającej z parametrów WebHttpBinding i WebHttpBehavior) z usługi WCF może wygenerować następujący wyjątek: Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed. Ten wyjątek występuje, ponieważ program WCF zastępuje wychodzące OperationContext z przychodzącym OperationContextelementem . Aby rozwiązać ten problem, utwórz element OperationContextScope w ramach operacji protokołu HTTP sieci Web WCF. Na przykład:

public string Echo(string input)  
{  
    using (new OperationContextScope(this.InnerChannel))  
    {  
        return base.Channel.Echo(input);  
    }  
}  

Zobacz też