WCF - İleti Boyutu Kotası Nasıl Artırılır


455

Veritabanından istemciye 1000 kayıt döndüren bir WCF hizmeti var. Bir ASP.NET WCF istemcim var (WCF tüketmek için asp.net web uygulaması projesinde hizmet referansı ekledim).

İstemci uygulamasını çalıştırdığımda aşağıdaki iletiyi alıyorum:

Gelen mesajlar için maksimum mesaj boyutu kotası (65536) aşıldı. Kotayı artırmak için, uygun bağlama öğesindeki MaxReceivedMessageSize özelliğini kullanın.

Herhangi bir yardım? İleti boyutu kotası nasıl artırılır?


Ben aynı sorunu vardı ama ben sadece düşmanca bir ağ hatası 400 var ama çözüm mesaj boyutu thingie ..
Bay W

2
Sorunu [bağlantı] [1] [1]
Ram

Neden varsayılan olarak bu kadar düşük ayarlanmış? Güvenlik?
Coops

@ Gerçekten güvenlik için çalışır. İletiler üzerinde bir kota ayarlayarak DDOS saldırılarının yürütülmesi (en azından biraz) daha zordur.
Peter van Kekem

Yanıtlar:


608

App.config veya Web.config dosyasında ileti boyutu kotalarını artırmak için böyle bir şeyin olmasını istersiniz :

<bindings>
    <basicHttpBinding>
        <binding name="basicHttp" allowCookies="true"
                 maxReceivedMessageSize="20000000" 
                 maxBufferSize="20000000"
                 maxBufferPoolSize="20000000">
            <readerQuotas maxDepth="32" 
                 maxArrayLength="200000000"
                 maxStringContentLength="200000000"/>
        </binding>
    </basicHttpBinding>
</bindings>

Bitiş noktası yapılandırmanızda cilt adını kullanın, ör.

...
bindingConfiguration="basicHttp"
...

Değerlerin gerekçesi basittir, çoğu iletiyi barındıracak kadar büyüktür. Bu numarayı ihtiyaçlarınıza uyacak şekilde ayarlayabilirsiniz. DOS varsayılan saldırılarını önlemek için düşük varsayılan değer temelde vardır. 20000000'ün dağıtılmış bir DOS saldırısının etkili olmasına izin verecek, varsayılan 64k boyutu, bu günlerde çoğu sunucuyu yenmesi için çok sayıda istemcinin kullanılmasını gerektirecektir.


20
Teşekkürler ... Bu değişikliğin istemci uygulamasının web.config dosyasında yapılması gerekmektedir.
bugBurger

8
Sunucuda da değiştirmeniz gerekebilir - büyük bir veri kümesinde bir WCF Yöntemi'ne parametre olarak göndermeniz gerektiğinde.
Nate

9
Çoğu mesajı karşılamak için yeterince büyük. Bu numarayı ihtiyaçlarınıza uyacak şekilde ayarlayabilirsiniz. Temelde DOS tipi saldırıları önlemek için vardır. 20000000 yapmak, dağıtılmış bir DOS saldırısının etkili olmasına izin verecek, varsayılan 64k boyutu, bu gün birçok sunucunun üstesinden gelmek için çok sayıda istemcinin kullanılmasını gerektirecek. S
Nate

18
İlgilenenler için, başka bir blogda maksimum boyutun 2147483647 olduğunu okudum. 20000000 bu sayıdan biraz daha küçük, bu yüzden en küçük sayıyı kullanarak hizmeti kesintiye uğratmadan uzaklaşabilirsiniz.
proudgeekdad

5
@Slauma Gelen parametre çok büyükse, sunucuda değiştirilmesi gerekir; aksi takdirde (ve büyük olasılıkla) değişikliğin istemci yapılandırma dosyasında yapılması gerekir, çünkü çok büyük olan hizmetin (parametresi değil) yanıtıdır.
Nate

156

WCF Test İstemcisi'ni kullanırken hala bu hata iletisini alıyorsanız, bunun nedeni istemcinin ayrı bir MaxBufferSize ayarı olmasıdır.

Sorunu gidermek için:

  1. Ağacın altındaki Yapılandırma Dosyası düğümüne sağ tıklayın
  2. SvcConfigEditor ile Düzenle'yi seçin

MaxBufferSize dahil olmak üzere düzenlenebilir ayarların bir listesi görünecektir.

Not: Otomatik oluşturulan proxy istemcileri de varsayılan olarak MaxBufferSize değerini 65536 olarak ayarlar.


8
Neden ah neden hep unutuyorum? +1
James Skemp

9
Vs2013 SvcConfigEditor yerine insanlar arıyorsanız WCF Yapılandırma Düzenle ile değiştirilir.
ZoomVirus

SVCconfigEditor bulamıyor musunuz?
Arul Sidthan

Bindings klasörü altında bulabilirsiniz, servis için bağlayıcı tıklayın ve orada.
Sameer Alibhai

Yapılandırma dosyanız otomatik olarak oluşturulmuşsa, kesinlikle bu şekilde yapmanız gerekir. Referansınızı her güncellediğinizde, app.config yeniden oluşturulur ve tekrar manuel olarak değiştirmeniz gerekecektir. Yine de VS'yi değiştirirseniz, yeni değişiklikler seçtiğiniz ayarları alacaktır.
kingfrito_5005

104

WCF bağlarınızı dinamik olarak oluşturuyorsanız, kullanılacak kod şöyledir:

BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.MaxReceivedMessageSize = Int32.MaxValue;
httpBinding.MaxBufferSize = Int32.MaxValue;
// Commented next statement since it is not required
// httpBinding.MaxBufferPoolSize = Int32.MaxValue;

Başlatmak için kullanabilirsiniz. Açıkça yapıcı yönteminizi kullanabilirsiniz.
aemre

46

WCF Testi Müşteri , bu kendi istemci yapılandırma vardır.

Test istemcisini çalıştırın ve aşağı kaydırın. Config File düğümüne çift tıklarsanız XML temsilini görürsünüz. Gördüğünüz gibi maxReceivedMessageSizeolduğunu 65536.

Bunu düzenlemek için Yapılandırma Dosyası ağacı düğümünü sağ tıklayın ve Birlikte Düzenle'yi seçin SvcConfigEditor. Düzenleyici açıldığında Ciltlemeler'i genişletin ve otomatik olarak oluşturulan bağlayıcıyı çift tıklayın.

Burada da dahil olmak üzere tüm özellikleri düzenleyebilirsiniz maxReceivedMessageSize. İşiniz bittiğinde Dosya - Kaydet'e tıklayın .

Son olarak, WCF Test İstemcisi penceresine geri döndüğünüzde, Araçlar - Seçenekler'i tıklayın .

NOT : Hizmetleri başlatırken Her zaman yeniden oluştur yapılandırmasının işaretini kaldırın .


2
Muhtemelen burada en iyi cevap!
Haris

3
Always regenerate configseçeneğin işaretini kaldırmak için not nedeniyle oy verin .
furier

Bence en basit çözümü. Bana biraz baş ağrısı kurtardı.
Jared Beach

Vs2013 SvcConfigEditor yerine insanlar arıyorsanız WCF Yapılandırma Düzenle ile değiştirilir.
ZoomVirus

Teşekkür ederim. Bir süredir kafamı kırıyorum, sorun Test İstemcisi yapılandırmasındayken sunucu yapılandırmasını tekrar tekrar değiştirme!
Fahad

24

Kolay yolu buldum

--- webconfig veya uygulama yapılandırma dosyasını sağ tıklayın ve WCF YAPILANDIRMAYI DÜZENLE öğesini tıklayın ve bingdigs ans yore servisini seçin ve sağ taraftaki maxReciveMessageSize şovunu çok sayıda verin ---


2
Harika bir cevaptı, buradan düzenleme yapabileceğimi bilmiyordum, Teşekkürler
albert sh

8

Sorunu çözdüm ... aşağıdaki gibi

    <bindings>
  <netTcpBinding>
    <binding name="ECMSBindingConfig" closeTimeout="00:10:00" openTimeout="00:10:00"
      sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
      maxReceivedMessageSize="2147483647" portSharingEnabled="true">
      <readerQuotas maxArrayLength="2147483647" maxNameTableCharCount="2147483647"
          maxStringContentLength="2147483647" maxDepth="2147483647"
          maxBytesPerRead="2147483647" />
      <security mode="None" />
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="ECMSServiceBehavior">
      <dataContractSerializer ignoreExtensionDataObject="true" maxItemsInObjectGraph="2147483647" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceTimeouts transactionTimeout="00:10:00" />
      <serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="100"
        maxConcurrentInstances="100" />
    </behavior>
  </serviceBehaviors>
</behaviors>

20
Bunun benim çözümümden farkı nedir? Bunun dışında yapılandırmanızın tüm ilgili olmayan bölümlerini ve ilgili parçaları dahil ettiniz ve seçtiğim 200m yerine mümkün olan maksimum değeri seçtiniz mi?
Nate

3
Bağlam da iyidir ... belki bu iki cevap birleştirilebilir mi?
Jeff

1
bu ayar sunucuda mı yoksa istemcide mi yapılandırılacak?
John Kenedy

8

CalculateRoute () kullanarak projemdeki Bing Maps WPF ile ilgili sorunumu çözdüm. Benim durumumdaki çözüm, "customBinding" bölümü için "httpTransport" özniteliğinde maxReceivedMessageSize ve maxReceivedMessageSize ayarını yapmaktı.

Applications.config dosyasında (es. MyApp.config) bu yapılandırmayı ayarladım:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IGeocodeService" />
            <binding name="BasicHttpBinding_IRouteService" />
        </basicHttpBinding>
        <customBinding>
            <binding name="CustomBinding_IGeocodeService">
                <binaryMessageEncoding />
              <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                                maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
                                bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                                keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
                                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                                useDefaultWebProxy="true" />
            </binding>
            <binding name="CustomBinding_IRouteService">
                <binaryMessageEncoding />
              <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                                maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
                                bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                                keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
                                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                                useDefaultWebProxy="true" />
            </binding>
        </customBinding>
    </bindings>
    <client>
        <endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocodeService"
            contract="BingServices.IGeocodeService" name="BasicHttpBinding_IGeocodeService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc/binaryHttp"
            binding="customBinding" bindingConfiguration="CustomBinding_IGeocodeService"
            contract="BingServices.IGeocodeService" name="CustomBinding_IGeocodeService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRouteService"
            contract="BingServices.IRouteService" name="BasicHttpBinding_IRouteService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc/binaryHttp"
            binding="customBinding" bindingConfiguration="CustomBinding_IRouteService"
            contract="BingServices.IRouteService" name="CustomBinding_IRouteService" />
    </client>
</system.serviceModel>

6

<bindings>
  <wsHttpBinding>
    <binding name="wsHttpBinding_Username" maxReceivedMessageSize="20000000"          maxBufferPoolSize="20000000">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName" establishSecurityContext="false"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<client>
  <endpoint
            binding="wsHttpBinding"
            bindingConfiguration="wsHttpBinding_Username"
            contract="Exchange.Exweb.ExchangeServices.ExchangeServicesGenericProxy.ExchangeServicesType"
            name="ServicesFacadeEndpoint" />
</client>


Cevabınızı göndermek için harika. "BağlamaConfiguration" değerinin bağlama adıyla eşleşmesi önemlidir. Örneğinizde "wsHttpBinding_Username".
Bruno Bieri

6

İçin HTTP:

<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" allowCookies="true"
             maxReceivedMessageSize="20000000" 
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
        <readerQuotas maxDepth="200" 
             maxArrayLength="200000000"
             maxBytesPerRead="4096"
             maxStringContentLength="200000000"
             maxNameTableCharCount="16384"/>
    </binding>
  </basicHttpBinding>
</bindings>

İçin TCP:

<bindings>
  <netTcpBinding>
    <binding name="tcpBinding"
             maxReceivedMessageSize="20000000"
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
      <readerQuotas maxDepth="200"
           maxArrayLength="200000000"
           maxStringContentLength="200000000"
           maxBytesPerRead="4096"
           maxNameTableCharCount="16384"/>
    </binding>
  </netTcpBinding>
</bindings>

ÖNEMLİ:

Çok sayıda bağlı nesnesi olan karmaşık bir nesneyi (örneğin: bir ağaç veri yapısı, çok sayıda nesnesi olan bir liste ...) iletmeye çalışırsanız, Kotaları nasıl artırdığınıza bakılmaksızın iletişim başarısız olur. Bu gibi durumlarda, içeren nesne sayısını artırmalısınız:

<behaviors>
  <serviceBehaviors>
    <behavior name="NewBehavior">
      ...
      <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

maxItemsInObjectGraphBenim için (hızlı) çözüm oldu. Ancak bunu arttırırken, kaynakları zorlayabilecek dev bir nesne grafiğinin aksine, uygulamanızın parçalar halinde veri istemesi için daha iyi bir çözüm olup olmadığını düşünmelisiniz.
Paul

6

Benim için tek yapmam maxReceivedMessageSize="2147483647"gereken istemci app.config dosyasına eklemek . Sunucu el değmeden kaldı.


5

Deneyimlerimden dikkate alınması gereken bir başka önemli konu ..

Havuzdan arabellekler hiçbir zaman uygulama etki alanı (yani Uygulama Havuzu) geri dönüştürülünceye kadar serbest bırakılmadığından, maxBufferPoolSize değerini en üst düzeye çıkarmak için kesinlikle tavsiye ETMEM.

Yoğun bir trafik dönemi, çok fazla belleğin kullanılmasına ve asla serbest bırakılmasına neden olabilir.

Daha fazla ayrıntı burada:


3

Yürütme giriş noktasının app.config dosyasının, varsa Web-Servis çağrılarını yöneten sınıf kütüphanesi projesinde değil, dikkate alınacağını unutmayın.

Örneğin, birim testini çalıştırırken hatayı alırsanız, test projesinde uygun yapılandırmayı ayarlamanız gerekir.


0

web.config bu ayarları kullanırken bu hatayı aldım

System.ServiceModel.ServiceActivationException

ayarları böyle yapıyorum:

      <service name="idst.Controllers.wcf.Service_Talks">
    <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_TalksAspNetAjaxBehavior"
      binding="webHttpBinding" contract="idst.Controllers.wcf.Service_Talks" />
  </service>
  <service name="idst.Controllers.wcf.Service_Project">
    <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_ProjectAspNetAjaxBehavior"
      binding="basicHttpBinding" bindingConfiguration="" bindingName="largBasicHttp"
      contract="idst.Controllers.wcf.Service_Project" />
  </service>
</services>

<bindings>
<basicHttpBinding>
    <binding name="largBasicHttp" allowCookies="true"
             maxReceivedMessageSize="20000000"
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
        <readerQuotas maxDepth="32"
             maxArrayLength="200000000"
             maxStringContentLength="200000000"/>
    </binding>
</basicHttpBinding>


4
Böylece, Nate'in cevabını kullanarak sorununuzu çözdünüz ve daha sonra kendi cevabınız olarak yayınladınız. Hiç hoş değil.
Mart'ta

@arcain Nates yanıtı, sık sık ortaya çıkması beklenen stok adları ve numaraları kullanılarak çok geneldi. Bu cevap çalınmadı, sadece doğru cevaptı. Tek bir doğru cevap olduğu için tekrarlanması gerekiyordu.
kingfrito_5005

@ kingfrito_5005 "Doğru" yanıt, yanıtlayan kişi bunu gönderdiğinde zaten buradaydı. Nate'in bindingsunsurunu açıkça kaldırdı ve cevabının bir parçası olarak onu yayınladı. Bu 2000000değerler oldukça farklı.
arcain

@arcain, bunların çok standart değerler olduğunu kabul etmiyorum, şirketim bunları bağlayıcı unsurlarımızda da kullanıyor.
kingfrito_5005
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.