Sdílet prostřednictvím


Řešení potíží s WCF – úvodní příručka

Toto téma uvádí řadu známých problémů, na které zákazníci narazili při vývoji klientů a služeb WCF. Pokud problém, na který narazíte, není v tomto seznamu, doporučujeme nakonfigurovat trasování pro vaši službu. Tím se vygeneruje trasovací soubor, který můžete zobrazit v prohlížeči trasovacích souborů a získat podrobné informace o výjimkách, ke kterým může dojít v rámci služby. Další informace o konfiguraci trasování najdete v tématu: Konfigurace trasování. Další informace o prohlížeči trasovacích souborů najdete v tématu: Nástroj Service Trace Viewer (SvcTraceViewer.exe).

  1. Po instalaci systému Windows 7 a IIS se při pokusu o přechod na službu WCF zobrazí následující chybová zpráva: Chyba HTTP 404.3 – Nenalezena

    Chyba HTTP 404.3 – Stránka, kterou požadujete, se nedá obsluhovat kvůli konfiguraci rozšíření. Pokud je stránka skriptem, přidejte obslužnou rutinu. Pokud se má soubor stáhnout, přidejte mapu MIME. Podrobná chyba InformationModule StaticFileModule.

  2. Někdy se mi při druhém požadavku zobrazí výjimka MessageSecurityException, pokud je můj klient nějakou dobu nečinný po prvním požadavku. Co se děje?

  3. Moje služba začne odmítat nové klienty po asi 10 klientech, kteří s ním pracují. Co se děje?

  4. Můžu načíst konfiguraci služby z jiného umístění než konfigurační soubor aplikace WCF?

  5. Moje služba a klient fungují skvěle, ale nemůžu je dostat do práce, když je klient na jiném počítači? Co se děje?

  6. Když vyvolám výjimku FaultException<,> kde typ je výjimka, vždy obdržím obecný typ FaultException v klientovi, a ne obecný typ. Co se děje?

  7. Zdá se, že jednosměrné operace a operace odpovědi na žádost vrací přibližně stejnou rychlost, když odpověď neobsahuje žádná data. Co se děje?

  8. Používám ve své službě certifikát X.509 a získám výjimku System.Security.Cryptography.CryptographicException. Co se děje?

  9. Změnil jsem první parametr operace z velkých písmen na malá písmena; teď můj klient vyvolá výjimku. Co se děje?

  10. Používám jeden ze svých trasovacích nástrojů a získám výjimku EndpointNotFoundException. Co se děje?

  11. Při volání webové aplikace HTTP WCF z aplikace WCF SOAP vrátí služba následující chybu: 405 Metoda Není povolena.

Jaká je základní adresa? Jak souvisí s adresou koncového bodu?

Po instalaci systému Windows 7 a IIS se při pokusu o přechod na službu WCF zobrazí následující chybová zpráva: Chyba HTTP 404.3 – Nenalezena

Úplná chybová zpráva:

Chyba HTTP 404.3 – Stránka, kterou požadujete, se nedá obsluhovat kvůli konfiguraci rozšíření. Pokud je stránka skriptem, přidejte obslužnou rutinu. Pokud se má soubor stáhnout, přidejte mapu MIME. Podrobná chyba InformationModule StaticFileModule.

K této chybové zprávě dochází v případě, že v Ovládací panely není explicitně nastavena aktivace HTTP služby Windows Communication Foundation. Chcete-li tuto možnost nastavit na Ovládací panely, klepněte na položku Programy v levém dolním rohu okna. Klikněte na Zapnout nebo vypnout funkce Systému Windows. Rozbalte rozhraní Microsoft .NET Framework 3.5.1 a vyberte aktivace HTTP služby Windows Communication Foundation.

Někdy se mi při druhém požadavku zobrazí výjimka MessageSecurityException, pokud je můj klient nějakou dobu nečinný po prvním požadavku. Co se děje?

Druhý požadavek může selhat především ze dvou důvodů: (1) vypršel časový limit relace nebo (2) webový server, který je hostitelem služby, je recyklován. V prvním případě je relace platná, dokud nevypršel časový limit služby. Pokud služba neobdrží požadavek od klienta během časového období zadaného ve vazbě služby (ReceiveTimeout), služba ukončí relaci zabezpečení. Následné zprávy klienta mají za MessageSecurityExceptionnásledek . Klient musí znovu vytvořit zabezpečenou relaci se službou, která bude odesílat budoucí zprávy nebo používat token kontextu stavového zabezpečení. Tokeny kontextu stavového zabezpečení také umožňují zabezpečené relaci přežít recyklaci webového serveru. Další informace o použití stavových zabezpečených kontextových tokenů v zabezpečené relaci naleznete v tématu Postupy: Vytvoření tokenu kontextu zabezpečení pro zabezpečenou relaci. Případně můžete zakázat zabezpečené relace. Pokud používáte <vazbu wsHttpBinding> , můžete vlastnost nastavit establishSecurityContext tak, aby false zakázala zabezpečené relace. Pokud chcete zakázat zabezpečené relace pro jiné vazby, musíte vytvořit vlastní vazbu. Podrobnosti o vytvoření vlastní vazby naleznete v tématu Postupy: Vytvoření vlastní vazby pomocí SecurityBindingElement. Než použijete některou z těchto možností, musíte porozumět požadavkům vaší aplikace na zabezpečení.

Moje služba začne odmítat nové klienty po asi 10 klientech, kteří s ním pracují. Co se děje?

Ve výchozím nastavení můžou mít služby pouze 10 souběžných relací. Proto pokud vazby služby používají relace, služba přijímá nová klientská připojení, dokud nedosáhne tohoto čísla, po kterém odmítne nová připojení klientů, dokud jedna z aktuálních relací nekončí. Více klientů můžete podporovat mnoha způsoby. Pokud vaše služba nevyžaduje relace, nepoužívejte relaci. (Další informace najdete v tématu Použití relací.) Další možností je zvýšit limit relace změnou hodnoty MaxConcurrentSessions vlastnosti na číslo odpovídající vašemu okolnostem.

Můžu načíst konfiguraci služby z jiného umístění než konfigurační soubor aplikace WCF?

Ano, ale musíte vytvořit vlastní ServiceHost třídu, která přepíše metodu ApplyConfiguration . Uvnitř této metody můžete nejprve volat základní konfiguraci načtení (pokud chcete také načíst standardní informace o konfiguraci), ale můžete také zcela nahradit systém načítání konfigurace. Pokud chcete načíst konfiguraci z konfiguračního souboru, který se liší od konfiguračního souboru aplikace, musíte konfigurační soubor analyzovat sami a načíst konfiguraci.

Následující příklad kódu ukazuje, jak přepsat metodu ApplyConfiguration a přímo nakonfigurovat koncový bod.

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

Moje služba a klient fungují skvěle, ale nemůžu je dostat do práce, když je klient na jiném počítači? Co se děje?

V závislosti na výjimce může dojít k několika problémům:

  • Možná budete muset změnit adresy koncového bodu klienta na název hostitele, nikoli na localhost.

  • Možná budete muset otevřít port pro aplikaci. Podrobnosti najdete v pokynech k bráně firewall z ukázek sady SDK.

  • Další možné problémy najdete v tématu Ukázky spuštění ukázek Windows Communication Foundation.

  • Pokud váš klient používá přihlašovací údaje systému Windows a výjimka je SecurityNegotiationException, nakonfigurujte protokol Kerberos následujícím způsobem.

    1. Přidejte přihlašovací údaje identity do elementu koncového bodu v souboru 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. Spusťte službu v místním prostředí pod účtem System nebo NetworkService. Spuštěním tohoto příkazu můžete vytvořit příkazové okno pod systémovým účtem:

      at 12:36 /interactive "cmd.exe"  
      
    3. Hostujte službu pod Internetová informační služba (IIS), která ve výchozím nastavení používá účet hlavního názvu služby (SPN).

    4. Zaregistrujte nový hlavní název služby (SPN) v doméně pomocí setSPN. Abyste to mohli udělat, musíte být správcem domény.

Další informace o protokolu Kerberos naleznete v tématu Koncepty zabezpečení používané ve WCF a:

Když vyvolám výjimku FaultException<,> kde typ je výjimka, vždy obdržím obecný typ FaultException v klientovi, a ne obecný typ. Co se děje?

Důrazně doporučujeme vytvořit vlastní datový typ chyby a deklarovat, že se jedná o podrobný typ ve smlouvě o chybě. Důvodem je použití systémových typů výjimek:

  • Vytvoří závislost typu, která odebere jednu z největších silných stránek aplikací orientovaných na služby.

  • Nelze záviset na výjimkách serializace standardním způsobem. Některé – třeba SecurityException– nemusí být vůbec serializovatelné.

  • Zveřejňuje interní podrobnosti implementace klientům. Další informace naleznete v tématu Určení a zpracování chyb v kontraktech a službách.

Pokud ale ladíte aplikaci, můžete serializovat informace o výjimce a vrátit je klientovi pomocí ServiceDebugBehavior třídy.

Zdá se, že jednosměrné operace a operace odpovědi na žádost vrací přibližně stejnou rychlost, když odpověď neobsahuje žádná data. Co se děje?

Určení, že operace je jedním ze způsobů, znamená to, že kontrakt operace přijímá vstupní zprávu a nevrací výstupní zprávu. Ve WCF se všechna volání klientů vrátí, když jsou odchozí data zapsána do přenosu nebo je vyvolána výjimka. Jednosměrné operace fungují stejným způsobem a mohou vyvolat, pokud služba nemůže být umístěna nebo blokována, pokud služba není připravena přijímat data ze sítě. Ve WCF to obvykle vede k jednosměrným voláním vracející se klientovi rychleji než žádost-odpověď; ale jakákoli podmínka, která zpomaluje odesílání odchozích dat přes síť, zpomaluje jednosměrné operace i operace odpovědi na požadavky. Další informace naleznete v tématu Jednosměrné služby a přístup ke službám pomocí klienta WCF.

Používám ve své službě certifikát X.509 a získám výjimku System.Security.Cryptography.CryptographicException. Co se děje?

K tomu obvykle dochází po změně uživatelského účtu, pod kterým běží pracovní proces služby IIS. Pokud například v systému Windows XP změníte výchozí uživatelský účet, pod kterým Aspnet_wp.exe běží z ASPNET na vlastní uživatelský účet, může se zobrazit tato chyba. Pokud používáte privátní klíč, proces, který ho používá, bude muset mít oprávnění pro přístup k souboru, který tento klíč ukládá.

V takovém případě musíte udělit oprávnění ke čtení přístupového oprávnění k účtu procesu pro soubor obsahující privátní klíč. Pokud je například pracovní proces služby IIS spuštěný pod účtem Bob, budete muset Bobovi udělit přístup ke čtení k souboru obsahujícímu privátní klíč.

Další informace o tom, jak udělit správný uživatelský účet přístup k souboru, který obsahuje privátní klíč pro konkrétní certifikát X.509, naleznete v tématu Postupy: Zpřístupnění certifikátů X.509 wcf.

Změnil jsem první parametr operace z velkých písmen na malá písmena; teď můj klient vyvolá výjimku. Co se děje?

Hodnoty názvů parametrů v podpisu operace jsou součástí kontraktu a rozlišují velká a malá písmena. System.ServiceModel.MessageParameterAttribute Atribut použijte, pokud potřebujete rozlišovat mezi názvem místního parametru a metadaty popisovanými operací pro klientské aplikace.

Používám jeden ze svých trasovacích nástrojů a získám výjimku EndpointNotFoundException. Co se děje?

Pokud používáte trasovací nástroj, který není systémem poskytovaný mechanismus trasování WCF a obdržíte EndpointNotFoundException zprávu, která indikuje, že došlo k neshodě filtru adres, musíte použít ClientViaBehavior třídu k nasměrování zpráv do nástroje trasování a nechat nástroj tyto zprávy přesměrovat na adresu služby. ClientViaBehavior Třída změní hlavičku Via adres tak, aby určila další síťovou adresu odděleně od konečného příjemce označeného hlavičkou To adres. V takovém případě ale neměňte adresu koncového bodu, která se používá k vytvoření To hodnoty.

Následující příklad kódu ukazuje ukázkový konfigurační soubor 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>  

Jaká je základní adresa? Jak souvisí s adresou koncového bodu?

Základní adresa je kořenová adresa třídy ServiceHost . Pokud do konfigurace služby přidáte třídu, načtou ServiceMetadataBehavior se z základní adresy HTTP všechny koncové body třídy WSDL (Web Services Description Language) pro všechny koncové body, které hostitel publikuje, a také z jakékoli relativní adresy poskytnuté chování metadat plus ?wsdl. Pokud znáte ASP.NET a IIS, je základní adresa ekvivalentní virtuálnímu adresáři.

Sdílení portu mezi koncovým bodem služby a koncovým bodem mex pomocí NetTcpBinding

Pokud zadáte základní adresu pro službu jako net.tcp://MyServer:8080/MyService a přidáte následující koncové body:

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

A pokud upravíte jedno z nastavení NetTcpBinding, jak je znázorněno v následujícím fragmentu konfigurace:

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

Zobrazí se chyba podobná následující: Neošetřená výjimka: System.ServiceModel.AddressAlreadyInUseException: Koncový bod IP adresy 0.0.0.0.0.0:9000 Tuto chybu můžete obejít zadáním plně kvalifikované adresy URL s jiným portem koncového bodu MEX, jak je znázorněno v následujícím fragmentu konfigurace:

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

Při volání webové aplikace HTTP WCF z aplikace WCF SOAP vrátí služba následující chybu: 405 Metoda Není povolena.

Volání webové aplikace HTTP WCF (služba, která používá WebHttpBinding a WebHttpBehavior) ze služby WCF může vygenerovat následující výjimku: Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed. K této výjimce dochází, protože WCF přepíše odchozí OperationContextOperationContextpošty příchozí . Chcete-li tento problém vyřešit, vytvořte OperationContextScope v rámci operace webové služby HTTP WCF. Příklad:

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

Viz také