>

RESTful WCF 서비스가 있는데 다음과 같은 오류가 발생합니다. 개체 그래프에서 직렬화 또는 역 직렬화 할 수있는 최대 항목 수는 '65536'입니다. 개체 그래프를 변경하거나 MaxItemsInObjectGraph 할당량을 늘리십시오.

이 문제를 해결했지만 분명히 그렇지 않다고 생각했습니다. 내 코드는 다음과 같습니다.

다음과 같이 커스텀 팩토리를 사용하는 .SVC 파일을 사용합니다 :

<%@ ServiceHost Language="C#" Debug="true" Service="myService" Factory="myCustomWebServiceHostFactory" %>

맞춤 팩토리 코드는 다음과 같습니다

public class myCustomWebServiceHost : WebServiceHost
{
    public myCustomWebServiceHost()
    {
    }
    public myCustomWebServiceHost(object singletonInstance, params Uri[] baseAddresses)
        : base(singletonInstance, baseAddresses)
    {
    }
    public myCustomWebServiceHost(Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
    }
    protected override void OnOpening()
    {
        foreach (var endpoint in Description.Endpoints)
        {
            var binding = endpoint.Binding as WebHttpBinding;
            if (binding != null)
            {
                const int fiveMegaBytes = 5242880;
                binding.MaxReceivedMessageSize = fiveMegaBytes;
                binding.MaxBufferSize = fiveMegaBytes;
                binding.MaxBufferPoolSize = fiveMegaBytes;
            }
        }
        base.OnOpening();
    }
}
class myCustomWebServiceHostFactory : WebServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new myCustomWebServiceHost(serviceType, baseAddresses);
    }
}

서비스 :

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceContract]
[ServiceBehavior(MaxItemsInObjectGraph = int.MaxValue)]
public class myService
{
...service implementation code goes here
}

고객 :

public class myClient
{
    WebChannelFactory<IMyService> cf;
    IMyService channel;
    public myClient()
    {
        WebHttpBinding _binding = new WebHttpBinding();
        _binding.MaxBufferPoolSize = 5000000;
        _binding.MaxBufferSize = 5000000;
        _binding.MaxReceivedMessageSize = 5000000;
        _binding.TransferMode = TransferMode.Streamed;
        _binding.ReceiveTimeout = new TimeSpan(0, 0, 30);
        _binding.ReaderQuotas.MaxArrayLength = 5000000;
        Uri _uri = new Uri("http://myserviceurl");
        cf = new WebChannelFactory<IMyService>(_binding, _uri);
        channel = cf.CreateChannel();
        foreach (OperationDescription op in cf.Endpoint.Contract.Operations)
        {
            var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
            if (dataContractBehavior != null)
            {
                dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }
    }
        ...client implementation code goes here
}

업데이트 : 약간의 문제 해결을 완료했습니다. 서버에서 직렬화 부분이 제대로 작동하는 것 같습니다. 브라우저에서 GET을 수행 할 수 있으며 모든 데이터를 XML 형식으로 수신합니다. 그래서 잘 작동합니다. 오류를 일으키는 직렬화 해제 부분 인 것 같습니다. 위의 myClient 코드를 살펴보면 DataContractSerializer 동작에 대한 MaxItemsInObjectGraph 속성을 설정하는 방법을 알 수 있습니다. 이 작업을 올바르게 수행하고 있습니까?

  • 답변 # 1

    알았다! 내 고객 코드가 잘못되었습니다. 이미다음에 MaxItemsInObjectGraph를 설정하고있었습니다. 이미 채널을 만들었습니다. 따라서 MaxItemInObjectGraph 속성은 이미 생성 된 채널에 영향을 미치지 않았습니다. (이 WCF 물건은 나에게 혼란 스럽습니다. 일반적으로 실제로 내가하는 일을 모르고 코드를 복사하여 붙여 넣는 것입니다) 올바른 코드는 다음과 같습니다.

           WebHttpBinding _binding = new WebHttpBinding();
            _binding.MaxBufferPoolSize = 5000000;
            _binding.MaxBufferSize = 5000000;
            _binding.MaxReceivedMessageSize = 5000000;
            _binding.TransferMode = TransferMode.Streamed;
            _binding.ReceiveTimeout = new TimeSpan(0, 0, 30);
            _binding.ReaderQuotas.MaxArrayLength = 5000000;
            Uri _uri = new Uri(http://myserviceurl);
            cf = new WebChannelFactory<IMyService>(_binding, _uri);
            foreach (OperationDescription op in cf.Endpoint.Contract.Operations)
            {
                var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
                if (dataContractBehavior != null)
                {
                    dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
                }
            }
            channel = cf.CreateChannel();
    
    

  • 답변 # 2

    클라이언트와 서비스의 동작을 사용하여 dataContractSerializer에서 MaxItemsInObjectGraph를 설정해야합니다. 예를 보려면 여기를 참조하십시오.

  • 답변 # 3

    클라이언트 측에서이를 달성하는 또 다른 방법은 사용자 정의 IEndPointBehavior 구현을 작성하는 것입니다. http://canbilgin.wordpress.com/2010/06/25/ 프로그래밍 방식으로 클라이언트 /에 대한 객체 설정 방법

    Winsor WcfFacility로 클라이언트를 구현할 때 특히 유용합니다

    public class ReaderQuotaExtension : IEndpointBehavior
    {
        #region Implementation of IEndpointBehavior
        public void Validate(ServiceEndpoint endpoint)
        {
        }
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            ModifyDataContractSerializerBehavior(endpoint);
        }
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            ModifyDataContractSerializerBehavior(endpoint);
        }
        #endregion
        private static void ModifyDataContractSerializerBehavior(ServiceEndpoint endpoint)
        {
            foreach (var behavior in endpoint.Contract.Operations.Select(operation => operation.Behaviors.Find<DataContractSerializerOperationBehavior>()))
            {
                behavior.MaxItemsInObjectGraph = 2147483647;
            }
        }
    
    

  • 답변 # 4

    일반 목록 또는 크기가 65536보다 큰 배열을 반환하는 경우 쿼리에서 선택 상위 60000을 사용하거나 60k 개를 초과하는 요소를 추가하지 않으면 문제가 해결됩니다.

  • 이전 php - Symfony2 기능 테스트에서 인증 된 사용자를 사용하는 방법은 무엇입니까?
  • 다음 php - 따옴표 사이의 공백을 제외한 모든 공백을 어떻게 찾을 수 있습니까?