WCF-메시지 크기 할당량을 늘리는 방법


454

데이터베이스에서 클라이언트로 1000 레코드를 반환하는 WCF 서비스가 있습니다. ASP.NET WCF 클라이언트가 있습니다 (WCF를 사용하기 위해 asp.net 웹 응용 프로그램 프로젝트에 서비스 참조를 추가했습니다).

클라이언트 응용 프로그램을 실행할 때 다음 메시지가 나타납니다.

수신 메시지의 최대 메시지 크기 할당량 (65536)을 초과했습니다. 할당량을 늘리려면 적절한 바인딩 요소에서 MaxReceivedMessageSize 속성을 사용하십시오.

어떤 도움? 메시지 크기 할당량을 늘리는 방법은 무엇입니까?


나는 같은 문제가 있었지만 방금 네트워크 오류 400이 발생하지 않았지만 해결책은 메시지 크기였습니다 ..
Mr W

2
[link] [1] [1]에 언급 된 단계를 사용하여 문제를 해결했습니다. stackoverflow.com/questions/7476853/…
Ram

기본적으로 왜 이렇게 낮게 설정되어 있습니까? 보안?
쿠프

실제로 보안을위한 @Coops. 예를 들어 메시지에 할당량을 설정하면 DDOS 공격이 (적어도 조금) 실행하기가 더 어렵습니다.
피터 반 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는 오늘날 대부분의 서버를 압도하는 많은 수의 클라이언트가 필요합니다.
Nate

18
관심있는 다른 사람들을 위해 다른 블로그에서 최대 크기는 2147483647입니다. 20000000 은이 숫자보다 약간 작으므로 서비스를 중단하지 않고 가장 작은 숫자를 사용하면 이해할 수 있습니다.
proudgeekdad

5
@Slauma 들어오는 매개 변수가 너무 큰 경우 서버에서 변경해야합니다. 그렇지 않으면 (그리고 그 가능성이 더 큰) 너무 큰 서비스 (매개 변수 아님)의 응답이므로 클라이언트 구성 파일에서 변경해야합니다.
Nate

155

WCF 테스트 클라이언트를 사용하는 동안이 오류 메시지가 계속 표시되면 클라이언트에 별도의 MaxBufferSize 가 있기 때문입니다. 설정 입니다.

문제를 해결하려면

  1. 구성 파일을 마우스 오른쪽 버튼으로 클릭트리 맨 아래 노드를
  2. SvcConfigEditor로 편집을 선택하십시오.

MaxBufferSize를 포함하여 편집 가능한 설정 목록이 나타납니다.

참고 : 자동 생성 프록시 클라이언트는 기본적으로 MaxBufferSize를 65536으로 설정합니다.


8
왜 이런 걸 항상 잊어 버려? +1
James Skemp

9
vs2013에서 SvcConfigEditor는 사람들이 찾고 있다면 WCF 구성 편집으로 바뀝니다.
ZoomVirus

SVCconfigEditor를 찾을 수 없습니까?
Arul Sidthan

바인딩 폴더 아래에서 서비스 바인딩을 클릭하면 그 안에 있습니다.
Sameer Alibhai

구성 파일이 자동으로 생성 된 경우 반드시이 방법으로 수행해야합니다. 참조를 업데이트 할 때마다 app.config가 재생성되며 수동으로 다시 변경해야합니다. 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

45

WCF 테스트 클라이언트 그 자체가 클라이언트의 설정을 가지고 있습니다.

테스트 클라이언트를 실행하고 맨 아래로 스크롤하십시오. 구성 파일 노드를 두 번 클릭하면 XML 표시가 나타납니다. 당신이 볼 수 있듯이 maxReceivedMessageSizeIS를65536 .

이를 편집하려면 구성 파일 트리 노드를 마우스 오른쪽 단추로 클릭하고 다음으로 편집을 선택하십시오. SvcConfigEditor . 편집기가 열리면 바인딩을 펼치고 자동으로 생성 된 바인딩을 두 번 클릭하십시오.

를 포함하여 여기에서 모든 속성을 편집 할 수 있습니다 maxReceivedMessageSize. 완료되면 파일-저장을 클릭 하십시오 .

마지막으로 WCF 테스트 클라이언트 창으로 돌아 오면 도구-옵션을 클릭하십시오 .

참고 : 서비스를 시작할 때 항상 구성 재생성을 선택 취소하십시오 .


2
아마도 가장 좋은 대답은 여기입니다!
Haris

3
Always regenerate config옵션의 선택을 취소하라는 메모 때문에 upvote .
furier

내 의견으로는 가장 간단합니다. 두통을 덜어주었습니다.
Jared Beach

vs2013에서 SvcConfigEditor는 사람들이 찾고 있다면 WCF 구성 편집으로 바뀝니다.
ZoomVirus

감사합니다. 테스트 클라이언트 구성에 문제가있을 때 잠시 동안 서버 구성을 변경하면서 고개를 저질렀습니다!
Fahad

24

나는 쉬운 길을 찾았다

--- webconfig 또는 app config 파일을 마우스 오른쪽 버튼으로 클릭하고 WCF 구성 편집을 클릭하고 선택 yore 서비스 및 오른쪽 표시 maxReciveMessageSize를 bingdigs해야합니다.


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 대신 가능한 최대 값을 선택 했습니까?
Nate

3
상황도 좋습니다 ... 아마도이 두 가지 답변이 합쳐질 수 있습니까?
Jeff

1
서버 또는 클라이언트에서 설정을 구성합니까?
존 케네디

8

CalculateRoute ()를 사용하여 프로젝트의 Bing Maps WPF에서 문제를 해결했습니다. 필자의 경우 솔루션은 "customBinding"섹션의 "httpTransport"속성에서 maxReceivedMessageSize 및 maxReceivedMessageSize를 설정했습니다.

applications.config 파일 (예 : 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나를 위해 (빠른) 솔루션이었다. 그러나이를 늘리면 리소스에 부담을 줄 수있는 거대한 객체 그래프가 아니라 애플리케이션이 더 나은 솔루션을 사용하여 청크 단위로 데이터를 요청하는지 여부를 고려해야합니다.
Paul

6

나를 maxReceivedMessageSize="2147483647"위해 클라이언트 app.config에 추가 하기 만하면됩니다. 서버는 그대로 남아 있습니다.


5

내 경험에서 고려해야 할 또 다른 중요한 ..

응용 프로그램 풀 (예 : 응용 프로그램 풀)이 재활용 될 때까지 풀의 버퍼가 해제되지 않기 때문에 maxBufferPoolSize를 최대화하지 않는 것이 좋습니다.

트래픽이 많을 경우 많은 메모리가 사용되어 해제되지 않을 수 있습니다.

자세한 내용은 여기 :


3

웹 서비스 호출을 관리하는 클래스 라이브러리 프로젝트의 항목이 아닌 실행 진입 점의 app.config가 고려된다는 것을 잊지 마십시오.

예를 들어 단위 테스트를 실행하는 동안 오류가 발생하면 테스트 프로젝트에서 적절한 구성을 설정해야합니다.


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 "올바른"답변은 답변자가이 게시물을 게시했을 때 이미 여기에 있습니다. 그는 Nate의 bindings요소를 분명히 들어 올리고 그의 답변의 일부로 다시 게시했습니다. 그 2000000가치는 상당히 다르다.
arcain

@arcain, 나는 그것들이 매우 표준적인 가치에 동의하지 않습니다. 우리 회사는 그것들을 바인딩 요소에서도 사용합니다.
kingfrito_5005
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.