Dela via


Snabbstart för WCF-felsökning

Det här avsnittet innehåller ett antal kända problem som kunder har stött på när de utvecklar WCF-klienter och -tjänster. Om problemet du stöter på inte finns i den här listan rekommenderar vi att du konfigurerar spårning för din tjänst. Detta genererar en spårningsfil som du kan visa med spårningsfilens visningsprogram och få detaljerad information om undantag som kan inträffa i tjänsten. Mer information om hur du konfigurerar spårning finns i: Konfigurera spårning. Mer information om visningsprogrammet för spårningsfiler finns i: Service Trace Viewer Tool (SvcTraceViewer.exe).

  1. När jag har installerat Windows 7 och IIS får jag följande felmeddelande när jag försöker bläddra till en WCF-tjänst: HTTP-fel 404.3 – Hittades inte

    HTTP-fel 404.3 – Hittades inte Sidan du begär kan inte hanteras på grund av tilläggskonfigurationen. Om sidan är ett skript lägger du till en hanterare. Om filen ska laddas ned lägger du till en MIME-karta. Detaljerad felinformationModule StaticFileModule.

  2. Ibland får jag en MessageSecurityException på den andra begäran om min klient är inaktiv en stund efter den första begäran. Vad händer?

  3. Min tjänst börjar avvisa nya klienter när cirka 10 klienter interagerar med den. Vad händer?

  4. Kan jag läsa in min tjänstkonfiguration från någon annan plats än WCF-programmets konfigurationsfil?

  5. Min tjänst och klient fungerar bra, men jag kan inte få dem att fungera när klienten är på en annan dator? Vad händer?

  6. När jag genererar ett FaultException-undantag<> där typen är ett undantag får jag alltid en allmän FaultException-typ på klienten och inte den generiska typen. Vad händer?

  7. Det verkar som om envägs- och begärandesvarsåtgärder returneras med ungefär samma hastighet när svaret inte innehåller några data. Vad händer?

  8. Jag använder ett X.509-certifikat med min tjänst och jag får en System.Security.Cryptography.CryptographicException. Vad händer?

  9. Jag ändrade den första parametern för en åtgärd från versaler till gemener. nu genererar min klient ett undantag. Vad händer?

  10. Jag använder ett av mina spårningsverktyg och jag får en EndpointNotFoundException. Vad händer?

  11. När du anropar ett WCF Web HTTP-program från ett WCF SOAP-program returnerar tjänsten följande fel: 405-metoden tillåts inte

Vilken är basadressen? Hur relaterar den till en slutpunktsadress?

När jag har installerat Windows 7 och IIS får jag följande felmeddelande när jag försöker bläddra till en WCF-tjänst: HTTP-fel 404.3 – Hittades inte

Det fullständiga felmeddelandet är:

HTTP-fel 404.3 – Hittades inte Sidan du begär kan inte hanteras på grund av tilläggskonfigurationen. Om sidan är ett skript lägger du till en hanterare. Om filen ska laddas ned lägger du till en MIME-karta. Detaljerad felinformationModule StaticFileModule.

Det här felmeddelandet uppstår när "Windows Communication Foundation HTTP-aktivering" inte uttryckligen anges i Kontrollpanelen. Om du vill ange detta går du till Kontrollpanelen genom att klicka på Program i fönstrets nedre vänstra hörn. Klicka på Aktivera eller inaktivera Windows-funktioner. Expandera Microsoft .NET Framework 3.5.1 och välj HTTP-aktivering för Windows Communication Foundation.

Ibland får jag en MessageSecurityException på den andra begäran om min klient är inaktiv en stund efter den första begäran. Vad händer?

Den andra begäran kan misslyckas främst av två orsaker: (1) sessionen har överskridit tidsgränsen eller (2) webbservern som är värd för tjänsten återvinns. I det första fallet är sessionen giltig tills tjänsten överskrider tidsgränsen. När tjänsten inte tar emot en begäran från klienten inom den tidsperiod som anges i tjänstens bindning (ReceiveTimeout), avslutar tjänsten säkerhetssessionen. Efterföljande klientmeddelanden resulterar i MessageSecurityException. Klienten måste återupprätta en säker session med tjänsten för att skicka framtida meddelanden eller använda en tillståndskänslig säkerhetskontexttoken. Tillståndskänsliga säkerhetskontexttoken gör det också möjligt för en säker session att överleva en webbserver som återvinns. Mer information om hur du använder tillståndskänsliga säkerhetskontexttoken i en säker session finns i Så här skapar du en säkerhetskontexttoken för en säker session. Du kan också inaktivera säkra sessioner. När du använder <wsHttpBinding-bindningen> kan du ange establishSecurityContext egenskapen till för false att inaktivera säkra sessioner. Om du vill inaktivera säkra sessioner för andra bindningar måste du skapa en anpassad bindning. Mer information om hur du skapar en anpassad bindning finns i Så här skapar du en anpassad bindning med hjälp av SecurityBindingElement. Innan du tillämpar något av dessa alternativ måste du förstå programmets säkerhetskrav.

Min tjänst börjar avvisa nya klienter när cirka 10 klienter interagerar med den. Vad händer?

Som standard kan tjänsterna bara ha 10 samtidiga sessioner. Om tjänstbindningarna använder sessioner accepterar tjänsten därför nya klientanslutningar tills den når det talet, varefter den nekar nya klientanslutningar tills en av de aktuella sessionerna slutar. Du kan stödja fler klienter på flera olika sätt. Om tjänsten inte kräver sessioner ska du inte använda en sessionskänslig bindning. (Mer information finns i Använda sessioner.) Ett annat alternativ är att öka sessionsgränsen genom att ändra värdet för MaxConcurrentSessions egenskapen till det tal som är lämpligt för din situation.

Kan jag läsa in min tjänstkonfiguration från någon annan plats än WCF-programmets konfigurationsfil?

Ja, du måste dock skapa en anpassad ServiceHost klass som åsidosätter ApplyConfiguration metoden. I den metoden kan du anropa basen för att läsa in konfigurationen först (om du vill läsa in standardkonfigurationsinformationen också) men du kan också helt ersätta konfigurationens inläsningssystem. Om du vill läsa in konfigurationen från en konfigurationsfil som skiljer sig från programkonfigurationsfilen måste du parsa konfigurationsfilen själv och läsa in konfigurationen.

Följande kodexempel visar hur du åsidosätter ApplyConfiguration metoden och konfigurerar en slutpunkt direkt.

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

Min tjänst och klient fungerar bra, men jag kan inte få dem att fungera när klienten är på en annan dator? Vad händer?

Beroende på undantaget kan det finnas flera problem:

  • Du kan behöva ändra klientslutpunktsadresserna till värdnamnet och inte "localhost".

  • Du kan behöva öppna porten för programmet. Mer information finns i Brandväggsinstruktioner från SDK-exemplen.

  • Andra möjliga problem finns i exempelavsnittet Köra Windows Communication Foundation-exempel.

  • Om klienten använder Windows-autentiseringsuppgifter och undantaget är en SecurityNegotiationExceptionkonfigurerar du Kerberos på följande sätt.

    1. Lägg till autentiseringsuppgifterna för identiteten i slutpunktselementet i klientens App.config-fil:

      <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. Kör den lokalt installerade tjänsten under System- eller NetworkService-kontot. Du kan köra det här kommandot för att skapa ett kommandofönster under systemkontot:

      at 12:36 /interactive "cmd.exe"  
      
    3. Värd för tjänsten under Internet Information Services (IIS), som som standard använder spn-kontot (tjänstens huvudnamn).

    4. Registrera ett nytt SPN med domänen med SetSPN. Du måste vara domänadministratör för att kunna göra detta.

Mer information om Kerberos-protokollet finns i Säkerhetsbegrepp som används i WCF och:

När jag genererar ett FaultException-undantag<> där typen är ett undantag får jag alltid en allmän FaultException-typ på klienten och inte den generiska typen. Vad händer?

Vi rekommenderar starkt att du skapar en egen typ av anpassade feldata och deklarerar det som informationstypen i ditt felkontrakt. Orsaken är att du använder undantagstyper som tillhandahålls av systemet:

  • Skapar ett typberoende som tar bort en av de största fördelarna med tjänstorienterade program.

  • Kan inte vara beroende av undantag som serialiseras på ett standard sätt. Vissa– till exempel SecurityException– kanske inte är serialiserbara alls.

  • Exponerar intern implementeringsinformation för klienter. Mer information finns i Ange och hantera fel i kontrakt och tjänster.

Om du felsöker ett program kan du dock serialisera undantagsinformation och returnera den till klienten med hjälp ServiceDebugBehavior av -klassen.

Det verkar som om envägs- och begärandesvarsåtgärder returneras med ungefär samma hastighet när svaret inte innehåller några data. Vad händer?

Att ange att en åtgärd är ett sätt innebär bara att åtgärdskontraktet accepterar ett indatameddelande och inte returnerar ett utdatameddelande. I WCF returneras alla klientanrop när utgående data har skrivits till tråden eller ett undantag utlöses. Enkelriktade åtgärder fungerar på samma sätt och de kan utlösas om tjänsten inte kan hittas eller blockeras om tjänsten inte är beredd att acceptera data från nätverket. Vanligtvis i WCF resulterar detta i enkelriktade anrop som återgår till klienten snabbare än begärandesvar. men alla villkor som saktar ned sändningen av utgående data via nätverket saktar ned enkelriktade åtgärder samt åtgärder för begäran-svar. Mer information finns i One-Way Services and Accessing Services Using a WCF Client (Enkelriktade tjänster och åtkomst till tjänster med hjälp av en WCF-klient).

Jag använder ett X.509-certifikat med min tjänst och jag får en System.Security.Cryptography.CryptographicException. Vad händer?

Detta inträffar ofta när du har ändrat användarkontot som IIS-arbetsprocessen körs under. Om du till exempel ändrar standardanvändarkontot som Aspnet_wp.exe körs under från ASPNET till ett anpassat användarkonto kan det här felet visas. Om du använder en privat nyckel måste den process som använder den ha behörighet att komma åt filen som lagrar nyckeln.

Om så är fallet måste du ge läsbehörighet till processens konto för filen som innehåller den privata nyckeln. Om till exempel IIS-arbetsprocessen körs under Bob-kontot måste du ge Bob läsbehörighet till filen som innehåller den privata nyckeln.

Mer information om hur du ger rätt användarkonto åtkomst till filen som innehåller den privata nyckeln för ett specifikt X.509-certifikat finns i Så här gör du X.509-certifikat tillgängliga för WCF.

Jag ändrade den första parametern för en åtgärd från versaler till gemener. nu genererar min klient ett undantag. Vad händer?

Värdena för parameternamnen i åtgärdssignaturen ingår i kontraktet och är skiftlägeskänsliga. System.ServiceModel.MessageParameterAttribute Använd attributet när du behöver skilja mellan det lokala parameternamnet och de metadata som beskriver åtgärden för klientprogram.

Jag använder ett av mina spårningsverktyg och jag får en EndpointNotFoundException. Vad händer?

Om du använder ett spårningsverktyg som inte är den systembaserade WCF-spårningsmekanismen och du får en EndpointNotFoundException som anger att det fanns ett adressfiltermatchningsfel måste du använda ClientViaBehavior klassen för att dirigera meddelandena till spårningsverktyget och låta verktyget omdirigera dessa meddelanden till tjänstadressen. Klassen ClientViaBehavior ändrar adressrubriken Via för att ange nästa nätverksadress separat från den ultimata mottagaren, vilket anges av adressrubriken To . När du gör detta ändrar du dock inte slutpunktsadressen, som används för att upprätta To värdet.

I följande kodexempel visas ett exempel på en klientkonfigurationsfil.

<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>  

Vilken är basadressen? Hur relaterar den till en slutpunktsadress?

En basadress är rotadressen för en ServiceHost klass. Om du lägger till en ServiceMetadataBehavior klass i tjänstkonfigurationen hämtas som standard WSDL (Web Services Description Language) för alla slutpunkter som värden publicerar från HTTP-basadressen, plus eventuella relativa adresser som anges till metadatabeteendet, plus "?wsdl". Om du är bekant med ASP.NET och IIS motsvarar basadressen den virtuella katalogen.

Dela en port mellan en tjänstslutpunkt och en mex-slutpunkt med hjälp av NetTcpBinding

Om du anger basadressen för en tjänst som net.tcp://MyServer:8080/MyService och lägger till följande slutpunkter:

<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>  

Och om du ändrar någon av NetTcpBinding-inställningarna enligt följande konfigurationsfragment:

<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>  

Du ser ett fel som liknar följande: Ohanterat undantag: System.ServiceModel.AddressAlreadyInUseException: Det finns redan en lyssnare på IP-slutpunkten 0.0.0.0:9000 Du kan kringgå det här felet genom att ange en fullständigt kvalificerad URL med en annan port för MEX-slutpunkten enligt följande konfigurationsfragment:

<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>  

När du anropar ett WCF Web HTTP-program från ett WCF SOAP-program returnerar tjänsten följande fel: 405-metoden tillåts inte

Att anropa ett WCF Web HTTP-program (en tjänst som använder WebHttpBinding och WebHttpBehavior) från en WCF-tjänst kan generera följande undantag: Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed. Det här undantaget inträffar eftersom WCF skriver över utgående OperationContext med inkommande OperationContext. Lös problemet genom att skapa en OperationContextScope i WCF Web HTTP-tjänståtgärden. Till exempel:

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

Se även