0

我继承了一个 WCF 组件,其中该服务是一个类似 SQL 查询的服务。它接收一个查询,然后将查询传递给另一个 Web 服务。问题是默认情况下,WCF Web 服务客户端只接受 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>

我试图在 wcfTestClient 配置中设置 maxReceivedMessageSize。我还编写了一个独立的 Web 服务客户端。两者都返回相同的 64k 最大消息错误。

我已经测试过不进行链接的 Web 服务调用,而是循环并返回一些虚拟数据,它能够返回我需要的所需数量的结果(这个 Web 服务是一个类似 SQL 查询的服务,它接受一个查询并将字符串结果返回给客户端)。因此,当 WCF 充当 DFS(Documentum 基础服务)Web 服务的 Web 服务客户端并且返回的响应消息超过 64k 限制时,似乎存在问题。如何在 WCF 中为 Web 服务客户端设置 maxReceivedMessageSize?

编辑:添加了 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[] { "\t\ttemp3 = ", 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("\t\t\tadding fieldName " + temp3[0].Trim());
                        fieldNames.Add(temp3[0].Trim());
                    }
                    else
                    {
                        DFSCore.log.Debug("\t\t\tadding 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] = result;
                    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;
    }
}
4

1 回答 1

0

您还需要在客户端配置文件中设置 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>

如果问题仍然存在,请随时告诉我。

于 2020-10-15T03:24:09.333 回答