Обнаружена квота максимального размера сообщения в WCF

#wcf #maxreceivedmessagesize

#wcf #maxreceivedmessagesize

Вопрос:

Я унаследовал компонент WCF, в котором служба представляет собой службу, подобную SQL-запросу. Он принимает запрос и, в свою очередь, передает запрос другой веб-службе. Проблема в том, что по умолчанию клиент веб-службы WCF принимает только 100 результатов. Хотя он может удалить это ограничение, после удаления он обнаруживает ошибку максимального размера сообщения для входящих сообщений (65536). Краткая архитектура приведена ниже. Клиент будет использовать службу WCF, которая, в свою очередь, выполняет другой вызов службы.

Краткая архитектура

Это WCF Web.config

 <system.serviceModel>
    <diagnostics performanceCounters="Default">
        <messageLogging logEntireMessage="true" />
    </diagnostics>
    <bindings>
        <basicHttpBinding>
            <binding name="basicBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
                <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="36384" />
            </binding>
        </basicHttpBinding>
        <webHttpBinding>
            <binding maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />
        </webHttpBinding>
    </bindings>
    <services>
        <service name="MYWCF.DfsWcf">
            <clear />
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="MYWCF.IDfsWcf">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <host>
                <baseAddresses>
                    <add baseAddress="http://mercury/MOM_WCF/" />
                </baseAddresses>
            </host>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>
  

Я попытался установить maxReceivedMessageSize в конфигурации WcfTestClient.
Я также написал автономный клиент веб-службы. Оба возвращают ту же ошибку сообщения 64k max.

Я протестировал не выполнение вызова веб-службы с цепочкой, а вместо этого зацикливание и возврат некоторых фиктивных данных, и он способен возвращать желаемое количество результатов, которые мне нужны (этот веб-сервис является сервисом, подобным SQL-запросу, где он принимает запрос и возвращает результаты строки клиенту). Таким образом, похоже, что проблема существует, когда WCF действует как клиент веб-службы для веб-службы DFS (Documentum Foundation Services), и что возвращенное ответное сообщение превысило ограничение в 64 КБ. Как мне установить maxReceivedMessageSize для клиента веб-службы в WCF?

Редактировать: добавлен код WCF и код, который он использует для вызова DFS.

     public List<String[]> DoQuery(String username, String password, String repository, String query)
    {
        log4net.Config.XmlConfigurator.Configure();
        log.Debug("DoQuery started..");
        List<String[]> results = new List<String[]>();
        try
        {
            var prop = new Properties();
            var dfs = new DFSCore();
            var serviceContext = dfs.GetServiceContext(repository, username, password, prop.Domain);
            var queryService = dfs.GetQueryService(serviceContext, prop.Address);
            log.Debug("Executing DQL: "   query);

            /*
            for (int i = 0; i < 3000; i  )
            {
                results.Add(new string[] { ""   i, "objectID="   i });
            }
            */

            //return results;
            return dfs.ExecuteDql(queryService, query, prop.DocBase, int.Parse(prop.MaxResultCount));
        }
        catch (Exception e)
        {
            log.Error(e);
            throw e;
        }
    }

   public List<String[]> ExecuteDql(IQueryService querySvc, String dqlQuery, String repositoryName, int maxResultCount)
    {
        log4net.Config.XmlConfigurator.Configure();
        var results = new List<String[]>();

        try
        {
            var query = new PassthroughQuery { QueryString = dqlQuery };
            query.AddRepository(repositoryName);
            var queryEx = new QueryExecution { CacheStrategyType = CacheStrategyType.DEFAULT_CACHE_STRATEGY };
            queryEx.MaxResultCount = maxResultCount;
            queryEx.MaxResultPerSource = maxResultCount;

            List<String> fieldNames = new List<String>();
            String[] temp = dqlQuery.Split(new String[] { "from" }, StringSplitOptions.None);

            if (temp[0].StartsWith("select "))
            {
                string fields = temp[0].Substring("select ".Length).Trim();
                DFSCore.log.Debug("fields = "   fields);
                string[] temp2 = fields.Split(new char[] { ',' });
                foreach (string field in temp2)
                {
                    DFSCore.log.Debug("tfield = "   field);
                    string[] temp3 = field.Split(new string[] { " as " }, StringSplitOptions.None);
                    DFSCore.log.Debug(string.Concat(new object[] { "tttemp3 = ", temp3, ", length = ", temp3.Length }));
                    if (temp3.Length == 1)
                    {
                        if (temp3[0].Contains("."))
                        {
                            temp3[0] = temp3[0].Split(new string[] { "." }, StringSplitOptions.None)[1];
                        }
                        DFSCore.log.Debug("tttadding fieldName "   temp3[0].Trim());
                        fieldNames.Add(temp3[0].Trim());
                    }
                    else
                    {
                        DFSCore.log.Debug("tttadding fieldName "   temp3[1].Trim());
                        fieldNames.Add(temp3[1].Trim());
                    }
                }
            }

            var queryResult = querySvc.Execute(query, queryEx, null);
            var dataPackage = queryResult.DataPackage;
            var dataObjects = dataPackage.DataObjects;

            int index = 0;
            //convert the results into a List<AclIdentity>
            foreach (var dObj in dataObjects)
            {
                var docProperties = dObj.Properties;
                String[] temp4 = new String[fieldNames.Count];

                for (int i = 0; i < fieldNames.Count; i  )
                {
                    String fieldName = fieldNames[i];
                    var result = docProperties.Get(fieldName).GetValueAsString();
                    temp4[i] = resu<
                    DFSCore.log.Debug(string.Concat(new object[] { "[", index, "] fieldName["   i   "] = ", fieldName, ", value = ", result }));
                }
                results.Add(temp4);
                index  ;
            }
        }
        catch (Exception e)
        {
            DFSCore.log.Error(e);
        }
        return results;
    }
}
  

Комментарии:

1. Как вы вызываете службу WCF? Какова ваша конфигурация на стороне клиента?

2. @DingPeng Привет, отредактировал вопрос, чтобы добавить код WCF и код, который он использует для вызова DFS.

3. Я все еще не вижу конфигурацию на стороне клиента.

4. Вы имеете в виду конфигурацию автономного клиента? В этом случае веб-служба WCF является одновременно сервером (для автономного клиента) и клиентом (для DFS). DoQuery() — это открытый метод веб-службы WCF. Он вызывает метод ExecuteDql() для выполнения вызова веб-службы в DFS. Для всего WCF существует только один Web.config.

5. Привет, проблема решена? Если мой ответ вам полезен, вы можете пометить его как ответ.

Ответ №1:

Вам также необходимо установить значение maxReceivedMessageSize в файле конфигурации клиента.

Установка maxReceivedMessageSize клиента повлияет на длину сообщения, получаемого клиентом, и не влияет на сообщение, получаемое службой. Ваш файл конфигурации настраивает maxReceivedMessageSize только на стороне сервера.

Файл конфигурации клиента:

 <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="basicBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"/>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:8733/Service1/"
            binding="basicHttpBinding" bindingConfiguration="basicBinding"
            contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
    </client>
</system.serviceModel>
  

Не стесняйтесь, дайте мне знать, если проблема не устранена.