Ошибка WCF "Размер, необходимый для буферизации содержимого XML, превышал буферную квоту" при бросании исключения FaultException

Я пытаюсь выкинуть FaultException на стороне сервера приложения WCF. Я использую DTO как полезную нагрузку для этого исключения. С некоторого момента (для добрых больших объектов) я начал получать "Размер, необходимый для буферизации исключения XML-контента, превышающего буферную квоту" на стороне клиента. Все обязательные параметры размера сообщения и maxDepth устанавливаются в значение big enouth, чтобы выйти из-под контроля. Кто-нибудь сталкивался с этой проблемой? Кажется, в интернете нет решения. Настройка

<dataContractSerializer maxItemsInObjectGraph="2147483647" ignoreExtensionDataObject="true" />

не помогло.

Ответ 1

Проблема была в параметре "MaxFaultSize" в ClientRuntime, значение по умолчанию - 65535, поэтому вы не можете передавать большую полезную нагрузку по ошибкам WCF по умолчанию. Чтобы изменить это значение, вы должны написать собственное конечное имя EndpointBehavior следующим образом:

public class MaxFaultSizeBehavior : IEndpointBehavior
{
    private readonly int _size;

    public MaxFaultSizeBehavior(int size)
    {
        _size = size;
    }


    public void Validate(ServiceEndpoint endpoint)
    {            
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {         
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {            
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MaxFaultSize = _size;
    }
}

и примените его к конечной точке в клиенте при создании прокси:

_clientProxy.Endpoint.Behaviors.Add(new MaxFaultSizeBehavior(1024000));

или, без прокси, просто запустите клиент, чтобы добавить поведение:

_client = new MyServiceClient();
((ClientBase<IMyService>) _client).Endpoint.Behaviors.Add(new MaxFaultSizeBehavior(1024000));

После этого все будет хорошо. Я потратил много времени на поиск ответа, надеюсь, что это поможет кому-то.

Ответ 2

Вы пытались изменить maxBufferSize? Я думаю, что это пример максимизации всех настроек, хотя я бы не стал копировать его напрямую.

<binding name="BasicHttpBinding_MyService" 
                maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" 
                receiveTimeout="00:40:00" openTimeout="00:40:00" 
                closeTimeout="00:40:00" sendTimeout="00:40:00">
                <readerQuotas maxDepth="2147483647" 
                    maxStringContentLength="2147483647" maxArrayLength="2147483647" 
                    maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
                <security mode="None"/>
</binding>

Ответ 3

Для тех из нас, кто застрял в Visual Basic, здесь VB-версия @ZlobnyiSerg - отличное решение. Вся заслуга ему.

Imports System.ServiceModel.Channels
Imports System.ServiceModel.Description
Imports System.ServiceModel.Dispatcher

Public Class MaxFaultSizeBehavior
    Implements IEndpointBehavior

    Private ReadOnly _size As Integer

    Public Sub New(ByVal size As Integer)
        _size = size
    End Sub

    Public Sub Validate(ByVal endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
    End Sub

    Public Sub AddBindingParameters(ByVal endpoint As ServiceEndpoint, ByVal bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
    End Sub

    Public Sub ApplyDispatchBehavior(ByVal endpoint As ServiceEndpoint, ByVal endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
    End Sub

    Public Sub ApplyClientBehavior(ByVal endpoint As ServiceEndpoint, ByVal clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
        clientRuntime.MaxFaultSize = _size
    End Sub
End Class