WCF - Cara Meningkatkan Kuota Ukuran Pesan

454

Saya memiliki Layanan WCF yang mengembalikan 1000 catatan dari database ke klien. Saya memiliki klien ASP.NET WCF (Saya telah menambahkan referensi layanan dalam proyek aplikasi web asp.net untuk mengkonsumsi WCF).

Saya mendapatkan pesan berikut ketika saya menjalankan aplikasi klien:

Kuota ukuran pesan maksimum untuk pesan masuk (65536) telah terlampaui. Untuk menambah kuota, gunakan properti MaxReceivedMessageSize pada elemen pengikatan yang sesuai.

Ada bantuan? Bagaimana cara meningkatkan kuota ukuran pesan?

bugBurger
sumber
Saya memiliki masalah yang sama tetapi saya baru saja mendapatkan kesalahan jaringan yang tidak ramah 400 tetapi solusinya adalah ukuran pesan.
Tn. W
2
Saya memecahkan masalah dengan menggunakan langkah-langkah yang disebutkan dalam [tautan] [1] [1]: stackoverflow.com/questions/7476853/…
Ram
Mengapa standarnya sangat rendah? Keamanan?
Coops
@Coops untuk keamanan memang. Dengan menetapkan kuota pada pesan misalnya serangan DDOS (setidaknya sedikit) lebih sulit untuk dieksekusi.
Peter van Kekem

Jawaban:

608

Anda akan menginginkan sesuatu seperti ini untuk meningkatkan kuota ukuran pesan, di file App.config atau Web.config :

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

Dan gunakan nama yang mengikat dalam konfigurasi titik akhir Anda mis

...
bindingConfiguration="basicHttp"
...

Pembenaran untuk nilai-nilai ini sederhana, mereka cukup besar untuk mengakomodasi sebagian besar pesan. Anda dapat menyetel nomor itu agar sesuai dengan kebutuhan Anda. Nilai default rendah pada dasarnya ada untuk mencegah serangan tipe DOS. Membuatnya 20000000 akan memungkinkan serangan DOS terdistribusi menjadi efektif, ukuran default 64k akan membutuhkan sejumlah besar klien untuk mengalahkan sebagian besar server saat ini.

Nate
sumber
20
Terima kasih..Perubahan ini perlu dibuat dalam file web.config aplikasi klien.
bugBurger
8
Anda mungkin juga perlu mengubahnya di server - jika Anda perlu mengirimkan set data besar sebagai parameter ke Metode WCF.
Nate
9
Cukup besar untuk mengakomodasi sebagian besar pesan. Anda dapat menyetel nomor itu agar sesuai dengan kebutuhan Anda. Itu pada dasarnya ada untuk mencegah serangan tipe DOS. Membuatnya 20000000 akan memungkinkan serangan DOS terdistribusi menjadi efektif, ukuran default 64k akan membutuhkan sejumlah besar klien untuk mengalahkan sebagian besar server hari ini.s
Nate
18
Bagi orang lain yang tertarik, saya membaca di blog lain bahwa ukuran maksimumnya adalah 2147483647. 20000000 sedikit lebih kecil dari angka ini, jadi menggunakan nomor terkecil yang bisa Anda dapatkan tanpa mengganggu layanan masuk akal.
proudgeekdad
5
@Slauma Itu perlu diubah di server jika parameter yang masuk terlalu besar; jika tidak (dan lebih mungkin) perubahan perlu dibuat dalam file konfigurasi klien, karena itu adalah respon dari layanan (bukan parameternya) yang terlalu besar.
Nate
155

Jika Anda masih mendapatkan pesan kesalahan ini saat menggunakan Klien Uji WCF, itu karena klien memiliki pengaturan MaxBufferSize yang terpisah .

Untuk memperbaiki masalah ini:

  1. Klik kanan pada simpul File Config di bagian bawah pohon
  2. Pilih Edit dengan SvcConfigEditor

Daftar pengaturan yang dapat diedit akan muncul, termasuk MaxBufferSize.

Catatan: Klien proksi yang dibuat secara otomatis juga menetapkan MaxBufferSize ke 65536 secara default.

Michael Rodrigues
sumber
8
Kenapa oh kenapa aku selalu lupa tentang ini? +1
James Skemp
9
Pada vs2013 SvcConfigEditor diganti dengan konfigurasi Edit WCF jika orang mencarinya.
ZoomVirus
Tidak dapat menemukan SVCconfigEditor?
Arul Sidthan
Anda akan menemukannya di bawah folder Bindings, klik pada binding untuk layanan dan ada di sana.
Sameer Alibhai
Jika file konfigurasi Anda dibuat secara otomatis, Anda harus melakukannya dengan cara ini. Setiap kali Anda memperbarui referensi Anda, itu akan mengembalikan app.config, dan Anda harus mengubahnya lagi secara manual. Jika Anda mengubahnya VS, perubahan baru akan mengakomodasi pengaturan yang Anda pilih.
kingfrito_5005
104

Jika Anda membuat binding WCF Anda secara dinamis, inilah kode yang harus digunakan:

BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.MaxReceivedMessageSize = Int32.MaxValue;
httpBinding.MaxBufferSize = Int32.MaxValue;
// Commented next statement since it is not required
// httpBinding.MaxBufferPoolSize = Int32.MaxValue;
Bharath K
sumber
Anda dapat menggunakannya untuk menginisialisasi. Jelas Anda dapat menggunakannya metode konstruktor Anda.
aemre
45

The WCF Test Klien memiliki itu konfigurasi klien sendiri.

Jalankan klien uji dan gulir ke bawah. Jika Anda mengklik dua kali simpul File Konfigurasi Anda akan melihat representasi XML. Seperti yang dapat Anda lihat maxReceivedMessageSizeadalah 65536.

Untuk mengedit ini, Klik Kanan node pohon Config File dan pilih Edit With SvcConfigEditor. Ketika editor membuka buka Bindings dan klik dua kali ikatan yang dihasilkan secara otomatis.

Anda dapat mengedit semua properti di sini, termasuk maxReceivedMessageSize. Setelah selesai klik File - Save .

Terakhir, ketika Anda kembali ke jendela WCF Test Client, klik Tools - Options .

CATATAN : Hapus centang pada konfigurasi Selalu regenerasi saat meluncurkan layanan .

Halaman Jodee Dex
sumber
2
Mungkin jawaban terbaik di sini!
Haris
3
dibatalkan karena catatan untuk menghapus centang Always regenerate configopsi.
Furier
Memecahkan paling sederhana menurut saya. Menyelamatkan saya sakit kepala.
Pantai Jared
Pada vs2013 SvcConfigEditor diganti dengan konfigurasi Edit WCF jika orang mencarinya.
ZoomVirus
Terima kasih. Sudah melanggar kepalaku untuk sementara waktu, mengubah konfigurasi server lagi dan lagi, ketika masalahnya dengan konfigurasi Klien Test!
Fahad
24

Saya menemukan cara mudah

--- klik kanan file konfigurasi webconfig atau aplikasi dan klik EDIT WCF CONFIGURATION dan dapatkan bingdigs dan pilih layanan dahulu dan tampilan kanan maxReciveMessageSize berikan jumlah besar ---

NC64
sumber
2
Itu adalah jawaban yang bagus, saya tidak tahu bahwa saya dapat mengedit dari sini, Terima kasih
albert sh
8

Saya memecahkan masalah ... sebagai berikut

    <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>
Rajesh Kuamr Chekuri
sumber
20
Bagaimana ini berbeda dari solusi saya? Selain Anda termasuk semua bagian yang tidak relevan dari konfigurasi Anda serta bagian yang relevan dan Anda memilih nilai maksimum yang mungkin daripada 200m yang saya pilih?
Nate
3
Konteksnya juga bagus ... mungkin kedua jawaban ini bisa digabung?
Jeff
1
Apakah pengaturan itu dikonfigurasikan di server atau klien?
John Kenedy
8

Saya memecahkan masalah saya di Bing Maps WPF pada proyek saya Menggunakan CalculateRoute (). Solusi dalam kasus saya adalah mengatur maxReceivedMessageSize dan maxReceivedMessageSize pada atribut "httpTransport" untuk bagian "customBinding".

Saya atur di file Applications.config (es. MyApp.config) konfigurasi ini:

<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>
Francesco Germinara
sumber
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>

Hemant Soni
sumber
Bagus untuk memposting jawaban Anda. Penting bahwa nilai "bindingConfiguration" cocok dengan nama yang mengikat. Dalam contoh Anda "wsHttpBinding_Username".
Bruno Bieri
6

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

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

PENTING:

Jika Anda mencoba untuk melewati objek kompleks yang memiliki banyak objek yang terhubung (misalnya: struktur data pohon, daftar yang memiliki banyak objek ...), komunikasi akan gagal tidak peduli bagaimana Anda meningkatkan kuota. Dalam kasus seperti itu, Anda harus meningkatkan jumlah objek yang mengandung:

<behaviors>
  <serviceBehaviors>
    <behavior name="NewBehavior">
      ...
      <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
Yakub
sumber
Itu maxItemsInObjectGraphsolusi (cepat) bagi saya. Tetapi ketika meningkatkan ini, Anda harus berpikir tentang apakah solusi yang lebih baik untuk aplikasi Anda untuk meminta data dalam potongan, sebagai lawan dari grafik objek besar yang dapat menyaring sumber daya.
Paul
6

Bagi saya, yang harus saya lakukan adalah menambahkan maxReceivedMessageSize="2147483647"ke app.config klien. Server dibiarkan tidak tersentuh.

ashilon
sumber
5

Hal penting lain yang perlu dipertimbangkan dari pengalaman saya ..

Saya akan sangat menyarankan TIDAK untuk memaksimalkan maxBufferPoolSize, karena buffer dari kumpulan tidak pernah dirilis sampai domain-aplikasi (yaitu Application Pool) didaur ulang.

Periode lalu lintas tinggi dapat menyebabkan banyak memori digunakan dan tidak pernah dirilis.

Lebih detail di sini:

Valerio Gentile
sumber
3

Jangan lupa bahwa app.config dari titik entri eksekusi akan dipertimbangkan, bukan proyek perpustakaan kelas yang mengelola panggilan Web-Service jika ada.

Misalnya jika Anda mendapatkan kesalahan saat menjalankan unit test, Anda perlu mengatur konfigurasi yang sesuai dalam proyek pengujian.

Mengobrol
sumber
0

saya mendapatkan kesalahan ini saat menggunakan pengaturan ini di web.config

System.ServiceModel.ServiceActivationException

saya mengatur pengaturan seperti ini:

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

FARHAD AFSAR
sumber
4
Jadi, Anda memperbaiki masalah Anda dengan menggunakan jawaban Nate dan kemudian mempostingnya sebagai milik Anda. Tidak keren.
arcain
@arcain Nates jawabannya sangat umum, menggunakan nama dan nomor stok yang dapat sering muncul. Jawaban ini tidak dicuri, itu hanya jawaban yang tepat. Karena hanya ada satu jawaban yang benar, itu pasti akan diulangi.
kingfrito_5005
@ kingfrito_5005 Jawaban "benar" sudah ada di sini ketika penjawab memposting ini. Dia cukup jelas mengangkat bindingselemen Nate dan mem-posting ulang sebagai bagian dari jawabannya. 2000000Nilai - nilai itu sangat berbeda.
arcain
@arcain, saya tidak setuju itu adalah nilai yang sangat standar, perusahaan saya juga menggunakannya dalam elemen mengikat kami.
kingfrito_5005