WCF - วิธีเพิ่มโควต้าขนาดข้อความ


455

ฉันมีบริการ WCF ซึ่งส่งกลับ 1,000 รายการจากฐานข้อมูลไปยังลูกค้า ฉันมีไคลเอนต์ ASP.NET WCF (ฉันได้เพิ่มการอ้างอิงบริการในโครงการแอปพลิเคชันเว็บ asp.net เพื่อบริโภค WCF)

ฉันได้รับข้อความต่อไปนี้เมื่อฉันเรียกใช้แอปพลิเคชันไคลเอนต์:

เกินโควต้าขนาดข้อความสูงสุดสำหรับข้อความขาเข้า (65536) เกินแล้ว เมื่อต้องการเพิ่มโควต้าใช้คุณสมบัติ MaxReceivedMessageSize บนองค์ประกอบการรวมที่เหมาะสม

ความช่วยเหลือใด ๆ วิธีเพิ่มโควต้าขนาดข้อความ


ฉันมีปัญหาเดียวกัน แต่ฉันเพิ่งได้รับข้อผิดพลาดเครือข่ายที่ไม่เป็นมิตร 400 แต่การแก้ปัญหาคือสิ่งขนาดข้อความ ..
Mr W

2
ฉันแก้ไขปัญหาโดยใช้ขั้นตอนที่กล่าวถึงใน [ลิงก์] [1] [1]: stackoverflow.com/questions/7476853/…
Ram

ทำไมค่าเริ่มต้นถึงต่ำมาก? การรักษาความปลอดภัย?
Coops

@Coops เพื่อความปลอดภัยแน่นอน โดยการตั้งค่าโควต้าข้อความเช่นการโจมตี DDOS นั้นยากที่จะดำเนินการ
Peter van Kekem

คำตอบ:


608

คุณจะต้องการสิ่งนี้เพื่อเพิ่มโควต้าขนาดข้อความในไฟล์App.configหรือ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>

และใช้ชื่อการรวมในการกำหนดค่าจุดสิ้นสุดของคุณเช่น

...
bindingConfiguration="basicHttp"
...

เหตุผลสำหรับค่านั้นง่ายมากพอที่จะรองรับข้อความส่วนใหญ่ได้ คุณสามารถปรับหมายเลขให้เหมาะกับความต้องการของคุณ ค่าเริ่มต้นต่ำนั้นโดยทั่วไปมีเพื่อป้องกันการโจมตีประเภท DOS 20000000 จะทำให้การโจมตีแบบกระจายของ DOS มีประสิทธิภาพขนาดเริ่มต้นที่ 64k จะต้องมีลูกค้าจำนวนมากเพื่อเอาชนะเซิร์ฟเวอร์ส่วนใหญ่ในปัจจุบัน


20
ขอบคุณ .. การเปลี่ยนแปลงนี้จำเป็นต้องทำในไฟล์ web.config ของแอปพลิเคชันไคลเอนต์
bugBurger

8
คุณอาจต้องเปลี่ยนมันบนเซิร์ฟเวอร์ - ในกรณีที่คุณต้องส่งชุดข้อมูลขนาดใหญ่เป็นพารามิเตอร์ไปยังวิธี WCF
Nate

9
มันใหญ่พอที่จะรองรับข้อความส่วนใหญ่ คุณสามารถปรับหมายเลขให้เหมาะกับความต้องการของคุณ มันมีพื้นเพื่อป้องกันการโจมตีประเภท DOS ทำให้ 20000000 อนุญาตให้การโจมตีแบบกระจายของ DOS มีประสิทธิภาพขนาดเริ่มต้น 64k จะต้องมีลูกค้าจำนวนมากเพื่อเอาชนะเซิร์ฟเวอร์ส่วนใหญ่ในวันนี้
เนท

18
สำหรับคนอื่นที่มีความสนใจฉันอ่านในบล็อกอื่นว่าขนาดสูงสุดคือ 2147483647 20000000 นั้นเล็กกว่าตัวเลขนี้เล็กน้อยดังนั้นการใช้ตัวเลขที่เล็กที่สุดที่คุณสามารถทำได้โดยไม่ขัดจังหวะการบริการ
proudgeekdad

5
@Slauma มันจะต้องมีการเปลี่ยนแปลงบนเซิร์ฟเวอร์หากพารามิเตอร์ที่เข้ามามีขนาดใหญ่เกินไป; ไม่เช่นนั้น (และมีโอกาสมากขึ้น) การเปลี่ยนแปลงจะต้องทำในไฟล์กำหนดค่าไคลเอ็นต์เนื่องจากเป็นการตอบสนองของบริการ (ไม่ใช่พารามิเตอร์) ที่มีขนาดใหญ่เกินไป
เนท

156

หากคุณยังคงได้รับข้อความแสดงข้อผิดพลาดนี้ในขณะที่ใช้ไคลเอ็นต์ทดสอบ WCF นั่นเป็นเพราะไคลเอ็นต์มีการตั้งค่า MaxBufferSizeแยกต่างหาก

วิธีแก้ไขปัญหา:

  1. คลิกขวาที่โหนดไฟล์กำหนดค่าที่ด้านล่างของทรี
  2. เลือกแก้ไขด้วย SvcConfigEditor

รายการการตั้งค่าที่แก้ไขได้จะปรากฏขึ้นรวมถึง MaxBufferSize

หมายเหตุ: ไคลเอ็นต์พร็อกซีที่สร้างขึ้นอัตโนมัติยังตั้งค่า MaxBufferSize เป็น 65536 โดยค่าเริ่มต้น


8
ทำไมโอ้ทำไมฉันถึงลืมเรื่องนี้ไปตลอด? +1
James Skemp

9
บน vs2013 SvcConfigEditor จะถูกแทนที่ด้วยแก้ไขการกำหนดค่า WCF หากผู้คนกำลังมองหามัน
ZoomVirus

ไม่พบ SVCconfigEditor ใช่ไหม
Arul Sidthan

คุณจะพบมันภายใต้โฟลเดอร์การผูกคลิกที่การผูกพันสำหรับการบริการและมันอยู่ในนั้น
Sameer Alibhai

หากไฟล์กำหนดค่าของคุณถูกสร้างขึ้นโดยอัตโนมัติคุณควรทำอย่างนี้ เมื่อใดก็ตามที่คุณอัปเดตข้อมูลอ้างอิงของคุณแอปจะทำการลงทะเบียนใหม่อีกครั้งและคุณจะต้องทำการเปลี่ยนแปลงอีกครั้งด้วยตนเอง หากคุณเปลี่ยนเป็น VS การเปลี่ยนแปลงใหม่จะรองรับการตั้งค่าที่คุณเลือก
kingfrito_5005

104

หากคุณกำลังสร้างการเชื่อมโยง WCF ของคุณแบบไดนามิกนี่คือรหัสที่จะใช้:

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

คุณสามารถใช้มันเริ่มต้น เห็นได้ชัดว่าคุณสามารถใช้มันเป็นวิธีการสร้างของคุณ
aemre

46

ไคลเอ็นต์ WCF ทดสอบมีการตั้งค่าของลูกค้าเอง

เรียกใช้ไคลเอนต์ทดสอบและเลื่อนไปที่ด้านล่าง หากคุณคลิกสองครั้งที่โหนดไฟล์กำหนดค่าคุณจะเห็นการแทนค่า XML ขณะที่คุณสามารถดูมีmaxReceivedMessageSize65536

หากต้องการแก้ไขนี้คลิกขวา Config SvcConfigEditorโหนดไฟล์และเลือกแก้ไขด้วย เมื่อเอดิเตอร์เปิดขยายการโยงและดับเบิลคลิกการโยงที่สร้างขึ้นโดยอัตโนมัติ

maxReceivedMessageSizeคุณสามารถแก้ไขคุณสมบัติทั้งหมดที่นี่รวมทั้ง เมื่อเสร็จแล้วให้คลิกไฟล์ - บันทึกบันทึก

สุดท้ายเมื่อคุณกลับมาที่หน้าต่าง WCF ทดสอบไคลเอ็นต์คลิกเครื่องมือ - ตัวเลือก

หมายเหตุ : ยกเลิกการทําเครื่องหมาย config การงอกใหม่เสมอเมื่อเปิดบริการ


2
อาจเป็นคำตอบที่ดีที่สุดที่นี่!
Haris

3
upvote เนื่องจากบันทึกย่อเพื่อยกเลิกการAlways regenerate configเลือกตัวเลือก
ขนยาว

แก้ปัญหาที่ง่ายที่สุดในความคิดของฉัน ช่วยให้ฉันปวดหัว
หาด Jared

บน vs2013 SvcConfigEditor จะถูกแทนที่ด้วยแก้ไขการกำหนดค่า WCF หากผู้คนกำลังมองหามัน
ZoomVirus

ขอบคุณ. รับหัวของฉันในขณะที่การเปลี่ยนแปลงการกำหนดค่าเซิร์ฟเวอร์อีกครั้งและอีกครั้งเมื่อเกิดปัญหากับการกำหนดค่าลูกค้าทดสอบ!
Fahad

24

ฉันพบวิธีที่ง่าย

--- คลิกขวาที่ไฟล์กำหนดค่า webconfig หรือ app แล้วคลิกแก้ไขการกำหนดค่า WCF และไปที่ bingdigs และเลือกบริการสมัยก่อนและแสดงด้านขวา maxReciveMessageSize ให้จำนวนมาก ---


2
มันเป็นคำตอบที่ยอดเยี่ยมฉันไม่รู้ว่าฉันสามารถแก้ไขได้จากที่นี่ขอบคุณ
อัลเบิร์ตดวลจุดโทษ

8

ฉันแก้ปัญหา ... ดังนี้

    <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
สิ่งนี้แตกต่างจากโซลูชันของฉันอย่างไร นอกเหนือจากที่คุณรวมส่วนที่ไม่เกี่ยวข้องทั้งหมดของการกำหนดค่าของคุณเช่นเดียวกับส่วนที่เกี่ยวข้องและคุณเลือกค่าสูงสุดที่เป็นไปได้แทน 200m ที่ฉันเลือก?
เนท

3
บริบทก็ดีเกินไป ... บางทีคำตอบทั้งสองข้อนี้อาจถูกรวมเข้าด้วยกันได้?
Jeff

1
ตั้งค่านั้นถูกกำหนดค่าในเซิร์ฟเวอร์หรือไคลเอนต์?
John Kenedy

8

ฉันแก้ไขปัญหาของฉันใน Bing Maps WPF ในโครงการของฉันโดยใช้ CalculateRoute () วิธีแก้ปัญหาในกรณีของฉันคือการตั้งค่าส่วน maxReceivedMessageSize และ maxReceivedMessageSize บนแอตทริบิวต์ "httpTransport" สำหรับ "customBinding"

ฉันตั้งค่าในไฟล์ applications.config (es. myApp.config) การกำหนดค่านี้:

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


เหมาะสำหรับการโพสต์คำตอบของคุณ เป็นสิ่งสำคัญที่ค่า "bindingConfiguration" ตรงกับชื่อการโยง ในตัวอย่างของคุณ "wsHttpBinding_Username"
Bruno Bieri

6

สำหรับ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>

สำหรับ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>

สิ่งสำคัญ:

หากคุณพยายามส่งผ่านวัตถุที่ซับซ้อนที่มีวัตถุเชื่อมต่ออยู่มากมาย (เช่นโครงสร้างข้อมูลแบบต้นไม้รายการที่มีวัตถุจำนวนมาก ... ) การสื่อสารจะล้มเหลวไม่ว่าคุณจะเพิ่มโควต้าหรือไม่ก็ตาม ในกรณีเช่นนี้คุณต้องเพิ่มจำนวนวัตถุที่มี:

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

นี่maxItemsInObjectGraphเป็นทางออก (ด่วน) สำหรับฉัน แต่เมื่อเพิ่มสิ่งนี้คุณควรพิจารณาว่าทางออกที่ดีกว่าสำหรับแอปพลิเคชันของคุณเพื่อขอข้อมูลเป็นกลุ่มหรือไม่เมื่อเทียบกับกราฟวัตถุขนาดใหญ่ที่อาจกดดันทรัพยากร
พอล

6

สำหรับฉันสิ่งที่ฉันต้องทำคือเพิ่มmaxReceivedMessageSize="2147483647"ไปยังไคลเอนต์ app.config เซิร์ฟเวอร์ไม่ถูกแตะต้อง


5

อีกสิ่งสำคัญที่ต้องพิจารณาจากประสบการณ์ของฉัน ..

ฉันขอแนะนำอย่างยิ่งว่าอย่าเพิ่ม maxBufferPoolSize ให้มากที่สุดเนื่องจากบัฟเฟอร์จากกลุ่มจะไม่ถูกนำออกใช้จนกว่าแอปพลิเคชันโดเมน (เช่นกลุ่มแอปพลิเคชัน) จะรีไซเคิล

ช่วงเวลาที่มีการรับส่งข้อมูลสูงอาจทำให้มีการใช้งานหน่วยความจำจำนวนมากและไม่เคยเปิดตัว

รายละเอียดเพิ่มเติมที่นี่:


3

อย่าลืมว่าแอพการตั้งค่าของจุดเข้าใช้งานจะได้รับการพิจารณาไม่ใช่หนึ่งในโครงการห้องสมุดคลาสที่จัดการการโทรผ่านเว็บหากมี

ตัวอย่างเช่นหากคุณได้รับข้อผิดพลาดขณะใช้การทดสอบหน่วยคุณจะต้องตั้งค่าการกำหนดค่าที่เหมาะสมในโครงการทดสอบ


0

ฉันได้รับข้อผิดพลาดนี้เมื่อใช้การตั้งค่านี้บน web.config

System.ServiceModel.ServiceActivationException

ฉันตั้งค่าเช่นนี้:

      <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
ดังนั้นคุณแก้ไขปัญหาของคุณโดยใช้คำตอบของ Nate แล้วโพสต์เป็นของคุณเอง ไม่เท่ห์
arcain

@arcain Nates คำตอบทั่วไปมากโดยใช้ชื่อหุ้นและหมายเลขที่คาดว่าจะเกิดบ่อย คำตอบนี้ไม่ได้ถูกขโมยมันเป็นเพียงคำตอบที่ถูกต้อง เนื่องจากมีคำตอบที่ถูกต้องเพียงข้อเดียวเท่านั้นจึงจำเป็นต้องทำซ้ำ
kingfrito_5005

@ kingfrito_5005 คำตอบ "ถูกต้อง" มาแล้วที่นี่เมื่อผู้ตอบตอบโพสต์สิ่งนี้ เขายกbindingsองค์ประกอบของเนทให้ชัดเจนและโพสต์ใหม่เป็นส่วนหนึ่งของคำตอบของเขา 2000000คุณค่าเหล่านั้นค่อนข้างแตกต่าง
arcain

@arcain ฉันไม่เห็นด้วยที่มีค่ามาตรฐานมาก บริษัท ของฉันใช้มันในองค์ประกอบที่มีผลผูกพันของเราเช่นกัน
kingfrito_5005
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.