Aracılığıyla paylaş


WCF Sorun Giderme Hızlı Başlangıç

Bu konu başlığı altında, müşterilerin WCF istemcileri ve hizmetleri geliştirirken karşılaştığı bir dizi bilinen sorun listelenmektedir. Çalıştığınız sorun bu listede yoksa, hizmetiniz için izlemeyi yapılandırmanızı öneririz. Bu, izleme dosyası görüntüleyicisi ile görüntüleyebileceğiniz bir izleme dosyası oluşturur ve hizmette oluşabilecek özel durumlar hakkında ayrıntılı bilgi alır. İzlemeyi yapılandırma hakkında daha fazla bilgi için bkz. İzlemeyi Yapılandırma. İzleme dosyası görüntüleyicisi hakkında daha fazla bilgi için bkz. Hizmet İzleme Görüntüleyici aracı (SvcTraceViewer.exe).

  1. Windows 7 ve IIS'yi yükledikten sonra, bir WCF hizmetine göz atmaya çalışırken şu hata iletisini alıyorum: HTTP Hatası 404.3 – Bulunamadı

    HTTP Hatası 404.3 – Bulunamadıİstelediğiniz sayfa, uzantı yapılandırması nedeniyle sunulamıyor. Sayfa bir betikse bir işleyici ekleyin. Dosyanın indirilmesi gerekiyorsa bir MIME eşlemesi ekleyin. Ayrıntılı Hata BilgileriModule StaticFileModule.

  2. bazen istemcim ilk istek sonrasında bir süre boşta kalırsa ikinci istekte MessageSecurityException alıyorum. Ne oluyor?

  3. Yaklaşık 10 istemci etkileşime geçtikten sonra hizmetim yeni istemcileri reddetmeye başlıyor. Ne oluyor?

  4. Hizmet yapılandırmamı WCF uygulamasının yapılandırma dosyası dışında bir yerden yükleyebilir miyim?

  5. Hizmetim ve istemcim harika çalışıyor, ancak istemci başka bir bilgisayardayken onları çalıştıramıyorum? Ne oluyor?

  6. Türün özel durum olduğu bir FaultException<Özel Durumu> attığımda, her zaman genel türü değil istemcide genel bir FaultException türü alıyorum. Ne oluyor?

  7. Tek yönlü ve istek-yanıt işlemleri, yanıt veri içermediğinde kabaca aynı hızda döndürülmektedir. Sorun nedir?

  8. Hizmetimle bir X.509 sertifikası kullanıyorum ve System.Security.Cryptography.CryptographicException alıyorum. Ne oluyor?

  9. Bir işlemin ilk parametresini büyük harften küçük harfe değiştirdim; şimdi istemcim bir özel durum oluşturur. Sorun nedir?

  10. İzleme araçlarımdan birini kullanıyorum ve EndpointNotFoundException alıyorum. Ne oluyor?

  11. WCF SOAP uygulamasından WCF Web HTTP uygulaması çağrılırken hizmet şu hatayı döndürür: 405 Yöntemine İzin Verilmiyor

Temel adres nedir? Uç nokta adresiyle ilişkisi nedir?

Windows 7 ve IIS'yi yükledikten sonra, bir WCF hizmetine göz atmaya çalışırken şu hata iletisini alıyorum: HTTP Hatası 404.3 – Bulunamadı

Hata iletisinin tamamı:

HTTP Hatası 404.3 – Bulunamadıİstelediğiniz sayfa, uzantı yapılandırması nedeniyle sunulamıyor. Sayfa bir betikse bir işleyici ekleyin. Dosyanın indirilmesi gerekiyorsa bir MIME eşlemesi ekleyin. Ayrıntılı Hata BilgileriModule StaticFileModule.

Bu hata iletisi, "Windows Communication Foundation HTTP Etkinleştirmesi" Denetim Masası açıkça ayarlanmadığında oluşur. Bunu ayarlamak için Denetim Masası gidin, pencerenin sol alt köşesindeki Programlar'a tıklayın. Windows özelliklerini aç veya kapat'a tıklayın. Microsoft .NET Framework 3.5.1'i genişletin ve Windows Communication Foundation HTTP Etkinleştirmesi'ni seçin.

bazen istemcim ilk istek sonrasında bir süre boşta kalırsa ikinci istekte MessageSecurityException alıyorum. Ne oluyor?

İkinci istek öncelikli olarak iki nedenden dolayı başarısız olabilir: (1) oturum zaman aşımına uğradı veya (2) hizmeti barındıran Web sunucusu geri dönüştürüldü. İlk durumda, hizmet zaman aşımına gelene kadar oturum geçerli olur. Hizmet, hizmetin bağlamasında ()ReceiveTimeout belirtilen süre içinde istemciden bir istek almadığında, hizmet güvenlik oturumunu sonlandırır. Sonraki istemci iletileri ile sonuçlanır MessageSecurityException. İstemcinin gelecekteki iletileri göndermek veya durum bilgisi olan bir güvenlik bağlamı belirteci kullanmak için hizmetle güvenli bir oturumu yeniden kurması gerekir. Durum bilgisi olan güvenlik bağlamı belirteçleri, bir Web sunucusunun geri dönüştürülmekte olan bir durumdan kurtulması için güvenli bir oturuma da olanak sağlar. Güvenli bir oturumda durum bilgisi olan güvenli bağlam belirteçlerini kullanma hakkında daha fazla bilgi için bkz . Nasıl yapılır: Güvenli Oturum için Güvenlik Bağlam Belirteci Oluşturma. Alternatif olarak, güvenli oturumları devre dışı bırakabilirsiniz. wsHttpBinding bağlamasını <kullandığınızda, güvenli oturumları devre dışı bırakmak için özelliğini olarak false ayarlayabilirsinizestablishSecurityContext.> Diğer bağlamalarda güvenli oturumları devre dışı bırakmak için özel bir bağlama oluşturmanız gerekir. Özel bağlama oluşturma hakkında ayrıntılı bilgi için bkz . Nasıl yapılır: SecurityBindingElement Kullanarak Özel Bağlama Oluşturma. Bu seçeneklerden herhangi birini uygulamadan önce uygulamanızın güvenlik gereksinimlerini anlamanız gerekir.

Yaklaşık 10 istemci etkileşime geçtikten sonra hizmetim yeni istemcileri reddetmeye başlıyor. Ne oluyor?

Varsayılan olarak, hizmetlerin yalnızca 10 eşzamanlı oturumu olabilir. Bu nedenle, hizmet bağlamaları oturumları kullanırsa, hizmet bu sayıya ulaşana kadar yeni istemci bağlantılarını kabul eder ve ardından geçerli oturumlardan biri bitene kadar yeni istemci bağlantılarını reddeder. Çeşitli yollarla daha fazla istemciyi destekleyebilirsiniz. Hizmetiniz oturum gerektirmiyorsa, oturumlu bağlama kullanmayın. (Daha fazla bilgi için bkz. Oturumları Kullanma.) Bir diğer seçenek de özelliğin değerini MaxConcurrentSessions sizin durumunuz için uygun sayıya değiştirerek oturum sınırını artırmaktır.

Hizmet yapılandırmamı WCF uygulamasının yapılandırma dosyası dışında bir yerden yükleyebilir miyim?

Evet, ancak yöntemini geçersiz kılan ApplyConfiguration özel ServiceHost bir sınıf oluşturmanız gerekir. Bu yöntemin içinde, önce yapılandırmayı yüklemek için tabanı çağırabilirsiniz (standart yapılandırma bilgilerini de yüklemek istiyorsanız) ancak yapılandırma yükleme sistemini tamamen değiştirebilirsiniz. Yapılandırmayı uygulama yapılandırma dosyasından farklı bir yapılandırma dosyasından yüklemek istiyorsanız, yapılandırma dosyasını kendiniz ayrıştırıp yapılandırmayı yüklemeniz gerekir.

Aşağıdaki kod örneği, yöntemini geçersiz kılmayı ve bir uç noktayı doğrudan yapılandırmayı ApplyConfiguration gösterir.

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

Hizmetim ve istemcim harika çalışıyor, ancak istemci başka bir bilgisayardayken onları çalıştıramıyorum? Ne oluyor?

Özel duruma bağlı olarak, çeşitli sorunlar olabilir:

  • İstemci uç noktası adreslerini "localhost" değil konak adıyla değiştirmeniz gerekebilir.

  • Uygulamanın bağlantı noktasını açmanız gerekebilir. Ayrıntılar için bkz . SDK örneklerinden Güvenlik Duvarı Yönergeleri .

  • Diğer olası sorunlar için Windows Communication Foundation Örneklerini Çalıştırma örnekleri konusuna bakın.

  • İstemciniz Windows kimlik bilgilerini kullanıyorsa ve özel durum bir SecurityNegotiationExceptionise Kerberos'ı aşağıdaki gibi yapılandırın.

    1. kimlik kimlik bilgilerini istemcinin App.config dosyasındaki uç nokta öğesine ekleyin:

      <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. Şirket içinde barındırılan hizmeti System veya NetworkService hesabı altında çalıştırın. Sistem hesabı altında bir komut penceresi oluşturmak için şu komutu çalıştırabilirsiniz:

      at 12:36 /interactive "cmd.exe"  
      
    3. Hizmeti, varsayılan olarak hizmet asıl adı (SPN) hesabını kullanan Internet Information Services (IIS) altında barındırın.

    4. SetSPN kullanarak etki alanına yeni bir SPN kaydedin. Bunu yapmak için etki alanı yöneticisi olmanız gerekir.

Kerberos protokolü hakkında daha fazla bilgi için bkz . WCF'de Kullanılan Güvenlik Kavramları ve:

Türün özel durum olduğu bir FaultException<Özel Durumu> attığımda, her zaman genel türü değil istemcide genel bir FaultException türü alıyorum. Ne oluyor?

Kendi özel hata veri türünüzü oluşturmanız ve hata sözleşmenizde ayrıntı türü olarak bunu bildirmeniz kesinlikle önerilir. Bunun nedeni, sistem tarafından sağlanan özel durum türlerinin kullanılmasıdır:

  • Hizmet odaklı uygulamaların en büyük güçlü yönlerinden birini kaldıran bir tür bağımlılığı oluşturur.

  • Standart bir şekilde seri hale getirme özel durumlarına bağımlı olamaz. Bazıları (örneğin SecurityException) hiç serileştirilebilir olmayabilir.

  • İç uygulama ayrıntılarını istemcilere sunar. Daha fazla bilgi için bkz . Sözleşmelerde ve Hizmetlerde Hataları Belirtme ve İşleme.

Ancak bir uygulamada hata ayıklarsanız, özel durum bilgilerini seri hale getirebilirsiniz ve sınıfını kullanarak istemciye ServiceDebugBehavior döndürebilirsiniz.

Tek yönlü ve istek-yanıt işlemleri, yanıt veri içermediğinde kabaca aynı hızda döndürülmektedir. Sorun nedir?

İşlemin tek yönlü olduğunu belirtmek, yalnızca işlem sözleşmesinin bir giriş iletisini kabul edip çıkış iletisi döndürmediği anlamına gelir. WCF'de, giden veriler kabloya yazıldığında veya bir özel durum oluştuğunda tüm istemci çağrıları döndürülmektedir. Tek yönlü işlemler aynı şekilde çalışır ve hizmet bulunamazsa veya hizmet ağdan gelen verileri kabul etmeye hazır değilse engellenemezse oluşturabilirler. Genellikle WCF'de bu, istemciye istek-yanıttan daha hızlı bir şekilde tek yönlü çağrılar döndürülerek sonuç verir; ancak giden verilerin ağ üzerinden gönderilmesini yavaşlatan tüm koşullar tek yönlü işlemlerin yanı sıra istek-yanıt işlemlerini de yavaşlatıyor. Daha fazla bilgi için bkz. WcF İstemcisi Kullanarak Tek Yönlü Hizmetler ve Hizmetlere Erişme.

Hizmetimle bir X.509 sertifikası kullanıyorum ve System.Security.Cryptography.CryptographicException alıyorum. Ne oluyor?

Bu genellikle IIS çalışan işleminin çalıştırıldığı kullanıcı hesabı değiştirildikten sonra oluşur. Örneğin, Windows XP'de, Aspnet_wp.exe altında çalıştığı varsayılan kullanıcı hesabını ASPNET'ten özel bir kullanıcı hesabına değiştirirseniz, bu hatayı görebilirsiniz. Özel anahtar kullanıyorsanız, bunu kullanan işlemin bu anahtarı depolayan dosyaya erişme izinlerine sahip olması gerekir.

Bu durumda, özel anahtarı içeren dosya için işlemin hesabına okuma erişimi ayrıcalıkları vermeniz gerekir. Örneğin, IIS çalışan işlemi Bob hesabı altında çalışıyorsa, Bob'a özel anahtarı içeren dosyaya okuma erişimi vermeniz gerekir.

Belirli bir X.509 sertifikasının özel anahtarını içeren dosyaya doğru kullanıcı hesabına erişim verme hakkında daha fazla bilgi için bkz . Nasıl yapılır: X.509 Sertifikalarını WCF için Erişilebilir Hale Getirme.

Bir işlemin ilk parametresini büyük harften küçük harfe değiştirdim; şimdi istemcim bir özel durum oluşturur. Sorun nedir?

İşlem imzasında parametre adlarının değerleri sözleşmenin bir parçasıdır ve büyük/küçük harfe duyarlıdır. System.ServiceModel.MessageParameterAttribute yerel parametre adı ile istemci uygulamaları için işlemi açıklayan meta veriler arasında ayrım yapmanız gerektiğinde özniteliğini kullanın.

İzleme araçlarımdan birini kullanıyorum ve EndpointNotFoundException alıyorum. Ne oluyor?

Sistem tarafından sağlanan WCF izleme mekanizması olmayan bir izleme aracı kullanıyorsanız ve adres filtresi uyuşmazlığı olduğunu belirten bir ileti alırsanız EndpointNotFoundException , iletileri izleme yardımcı programına yönlendirmek ve yardımcı programın bu iletileri hizmet adresine yönlendirmesini sağlamak için sınıfını kullanmanız ClientViaBehavior gerekir. sınıfı, ClientViaBehavior adresleme üst bilgisi tarafından To belirtilen nihai alıcıdan ayrı olarak sonraki ağ adresini belirtmek için adresleme üst bilgisini değiştirirVia. Ancak bunu yaparken, değeri oluşturmak için kullanılan uç nokta adresini değiştirmeyin To .

Aşağıdaki kod örneğinde örnek bir istemci yapılandırma dosyası gösterilmektedir.

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

Temel adres nedir? Uç nokta adresiyle ilişkisi nedir?

Temel adres, bir ServiceHost sınıfın kök adresidir. Varsayılan olarak, hizmet yapılandırmanıza bir ServiceMetadataBehavior sınıf eklerseniz, konağın yayımladığı tüm uç noktalar için Web Hizmetleri Açıklama Dili (WSDL) HTTP temel adresinden ve meta veri davranışına sağlanan göreli adreslerden ve ayrıca "?wsdl" öğesinden alınır. ASP.NET ve IIS hakkında bilginiz varsa, temel adres sanal dizine eşdeğerdir.

NetTcpBinding kullanarak hizmet uç noktası ile mex uç noktası arasında bağlantı noktası paylaşma

Bir hizmetin temel adresini net.tcp://MyServer:8080/MyService olarak belirtir ve aşağıdaki uç noktaları eklerseniz:

<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şağıdaki yapılandırma parçacığında gösterildiği gibi NetTcpBinding ayarlarından birini değiştirirseniz:

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

Aşağıdaki gibi bir hata görürsünüz: İşlenmeyen Özel Durum: System.ServiceModel.AddressAlreadyInUseException: 0.0.0.0:9000 IP uç noktasında zaten bir dinleyici var Aşağıdaki yapılandırma kod parçacığında gösterildiği gibi MEX uç noktası için farklı bir bağlantı noktasına sahip tam URL belirterek bu hataya geçici bir çözüm bulabilirsiniz:

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

WCF SOAP uygulamasından WCF Web HTTP uygulaması çağrılırken hizmet şu hatayı döndürür: 405 Yöntemine İzin Verilmiyor

WCF hizmetinden bir WCF Web HTTP uygulamasının (ve WebHttpBehaviorkullanan WebHttpBinding bir hizmet) çağrılması şu özel durumu oluşturabilir: Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed. WcF gelen OperationContextile gidenin OperationContext üzerine yazdığı için bu özel durum oluşur. Bu sorunu çözmek için WCF Web HTTP hizmeti işlemi içinde bir OperationContextScope oluşturun. Örneğin:

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

Ayrıca bkz.