Aracılığıyla paylaş


WCF Sorunlarını Giderme Hızlı Başlangıcı

Bu konu başlığı altında, müşterilerin WCF istemcileri ve hizmetleri geliştirirken karşılaştığı bir dizi bilinen sorun listelenmektedir. Karşılaştığınız sorun bu listede yoksa, hizmetiniz için izleme 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 Bilgileri Modülü Static Dosya Modülü.

  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ı

Tam hata iletisi:

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 Bilgileri Modülü Static Dosya Modülü.

Bu hata iletisi, Denetim Masası'nda "Windows Communication Foundation HTTP Etkinleştirmesi" açıkça ayarlanmadığında oluşur. Bunu ayarlamak için Denetim Masası'na 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 MessageSecurityException ile sonuçlanır. İstemcinin, gelecekteki iletileri gönderebilmek veya durum bilgisi içeren bir güvenlik bağlamı belirteci kullanabilmek için hizmetle güvenli bir oturumu yeniden kurması gereklidir. Durum bilgisine sahip güvenlik bağlamı belirteçleri, bir Web sunucusunun yeniden başlatılması durumunda güvenli bir oturumun sürdürülmesine olanak tanır. 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 establishSecurityContext özelliğini false olarak ayarlayabilirsiniz. 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 ServiceHost yöntemini geçersiz kılan özel bir ApplyConfiguration 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, ApplyConfiguration yöntemini geçersiz kılmayı ve bir uç noktayı doğrudan nasıl yapılandıracağınızı 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, ana bilgisayar adı olarak 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 endpoint öğ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. Yerel olarak 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 hata durumu oluştuğunda tüm istemci çağrıları geri döner. Tek yönlü işlemler aynı şekilde çalışır ve eğer hizmet bulunamazsa bir hata fırlatabilir veya hizmetin ağdan gelen verileri kabul etmeye hazır olmaması durumunda işlemi engelleyebilir. 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. One-Way Hizmetler ve WCF İstemcisi Kullanarak 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. ClientViaBehavior sınıfı, Via adresleme üst bilgisini değiştirerek, To adresleme üst bilgisi tarafından belirtilen nihai alıcıdan ayrı olarak sonraki ağ adresini belirtir. 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, ana bilgisayarı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 adresten, artı "?wsdl" eklenerek elde edilir. 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>  

tr-TR: Aşağıdaki gibi bir hata görürsünüz: Yakalanmamış İstisna: 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ı kullanarak tam nitelikli bir URL belirterek bu hatadan kaçınabilirsiniz.

<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, WebHttpBinding ve WebHttpBehavior kullanan bir WCF Web HTTP uygulaması çağrıldığında şu istisna oluşabilir: Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed. Bu istisna, WCF'nin gelen OperationContext ile giden OperationContext üzerine yazmasından dolayı 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 bakınız