C# WCF web服务的响应大小限制

C# WCF web服务的响应大小限制,c#,.net,iis,wcf,C#,.net,Iis,Wcf,我使用basicHttpBinding在IIS中托管WCF服务。WCF web服务使用ADO.Net查询后端SQL Server 2008,并向WCF服务的客户端返回数据表 我发现当返回的DataTable很大时,会出现异常,称http连接被IIS关闭。有什么问题吗?如何设置更大的响应大小?另一个想法是对象的序列化大小是否有任何硬限制(我想可能DataTable实例太大而无法序列化?) IIS返回的错误信息为: 异常消息: 接收请求时出错 HTTP对的响应 . 这 可能是由于服务端点 绑定不使用

我使用basicHttpBinding在IIS中托管WCF服务。WCF web服务使用ADO.Net查询后端SQL Server 2008,并向WCF服务的客户端返回数据表

我发现当返回的DataTable很大时,会出现异常,称http连接被IIS关闭。有什么问题吗?如何设置更大的响应大小?另一个想法是对象的序列化大小是否有任何硬限制(我想可能DataTable实例太大而无法序列化?)

IIS返回的错误信息为:

异常消息:

接收请求时出错 HTTP对的响应 . 这 可能是由于服务端点 绑定不使用HTTP协议。 这也可能是由于HTTP 请求上下文正在被 服务器(可能是由于服务原因) 关闭)。有关详细信息,请参阅服务器日志 更多细节

{“基础连接已关闭:发生意外错误 在接收时。”}

这是我在web.config中托管的服务器端的全部源代码,默认值不变。因为我在IIS中托管,所以我使用basicHttpBinding

public class StudentManagement : IStudentManagement
{
    public DataTable Poll(int Id)
    {
        return MakeParentTable();
    }

    private DataTable MakeParentTable()
    {
        // Create a new DataTable.
        System.Data.DataTable table = new DataTable("ParentTable");
        // Declare variables for DataColumn and DataRow objects.
        DataColumn column;
        DataRow row;

        // Create new DataColumn, set DataType, 
        // ColumnName and add to DataTable.    
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.Int32");
        column.ColumnName = "id";
        column.ReadOnly = true;
        column.Unique = true;
        // Add the Column to the DataColumnCollection.
        table.Columns.Add(column);

        // Create second column.
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.String");
        column.ColumnName = "ParentItem";
        column.AutoIncrement = false;
        column.Caption = "ParentItem";
        column.ReadOnly = false;
        column.Unique = false;
        // Add the column to the table.
        table.Columns.Add(column);

        // Make the ID column the primary key column.
        DataColumn[] PrimaryKeyColumns = new DataColumn[1];
        PrimaryKeyColumns[0] = table.Columns["id"];
        table.PrimaryKey = PrimaryKeyColumns;

        // Create three new DataRow objects and add 
        // them to the DataTable
        for (int i = 0; i <= 1000000; i++)
        {
            row = table.NewRow();
            row["id"] = i;
            row["ParentItem"] = "ParentItem " + i;
            table.Rows.Add(row);
        }

        return table;
    }
}
客户端web.config:

<binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00"
    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    allowCookies="false" bypassProxyOnLocal="false" 
    hostNameComparisonMode="StrongWildcard"
    maxBufferSize="1000000000" maxBufferPoolSize="1000000000" 
    maxReceivedMessageSize="1000000000"
    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
    useDefaultWebProxy="true">
    <readerQuotas maxDepth="32" maxStringContentLength="1000000000" 
        maxArrayLength="1000000000"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">          
      <dataContractSerializer maxItemsInObjectGraph="100000"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

<services>
  <service behaviorConfiguration="MyServiceBehavior" name="Company.MyService">
    <!-- etc -->
  </service>
</services>

编辑2:

客户端app.config的流模式配置

    <basicHttpBinding>
      <binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00"
        openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="1500000000" maxBufferPoolSize="1500000000" maxReceivedMessageSize="1500000000"
        messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed"
        useDefaultWebProxy="true">
        <readerQuotas maxDepth="1500000000" maxStringContentLength="1500000000"
          maxArrayLength="1500000000" maxBytesPerRead="1500000000" maxNameTableCharCount="1500000000" />
        <security mode="None">
          <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
          <message clientCredentialType="UserName" algorithmSuite="Default" />
        </security>
      </binding>
    </basicHttpBinding>

流模式的服务器端web.config

  <basicHttpBinding>
    <binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00"
        openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="1000000000" maxBufferPoolSize="1000000000" maxReceivedMessageSize="1000000000"
        messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed"
        useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="1000000000" maxArrayLength="1000000000"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>

您可以使用多种缓冲区大小-默认情况下它们保持相当小(64K)以避免拒绝服务攻击,但如果需要,您可以增加这些大小:

 <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="largebuffers" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" 
                hostNameComparisonMode="StrongWildcard"
                maxBufferSize="524288" maxBufferPoolSize="524288" 
                maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" 
                              maxArrayLength="16384" maxBytesPerRead="4096" 
                              maxNameTableCharCount="16384" />
            </binding>
        </basicHttpBinding>
    </bindings>

请查看绑定中的“MaxBufferSize”、“MaxBufferPoolSize”、“MaxReceivedMessageSize”设置,以及
部分中的各种设置

我会尝试先增加“MaxBufferSize”和“MaxBufferPoolSize”,看看这是否有帮助——其他大多数设置应该更适合服务接收和处理消息的时间

对于序列化回的对象的大小没有硬性限制。但是,DataTable确实会带来很大的开销,如果您在客户端并不真正需要DataTable功能,您也可以在服务器上进行转换,只发送一个对象集合或通用列表,而不是重载DataTable对象

此外,如果您经常发回大量数据,您可能还需要调查WCF的流媒体功能(例如,如果您返回图片、视频等)。
Marc

乔治,发生这种情况时,一定要查看事件日志。查看WCF或任何其他组件是否记录了错误

另外,尝试打开WCF跟踪,查看是否存在未被记录的内部错误。您可能需要使跟踪变得详细才能看到它,但请看一看,看看有什么


仅仅因为你从IIS中得到了一个模糊的错误,并不意味着在某个地方没有更多更好的信息可用。毕竟,错误消息确实说,“有关更多详细信息,请参阅服务器日志。”

请参阅以下代码片段

<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>

也许会对某人有所帮助

我也犯了同样的错误。通过在服务器端web.config中将MaxItemsInObjectGraph属性(设置为大值)来解决此问题:

<binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00"
    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    allowCookies="false" bypassProxyOnLocal="false" 
    hostNameComparisonMode="StrongWildcard"
    maxBufferSize="1000000000" maxBufferPoolSize="1000000000" 
    maxReceivedMessageSize="1000000000"
    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
    useDefaultWebProxy="true">
    <readerQuotas maxDepth="32" maxStringContentLength="1000000000" 
        maxArrayLength="1000000000"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">          
      <dataContractSerializer maxItemsInObjectGraph="100000"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

<services>
  <service behaviorConfiguration="MyServiceBehavior" name="Company.MyService">
    <!-- etc -->
  </service>
</services>


从这里了解到:

检查这个问题,这个问题是关于请求大小限制的,这个问题是关于响应大小限制的。对我的问题有什么想法或解决方案吗?:-)Hi George的可能重复:添加了MaxBufferSize-是的,MaxReceivedMEssageSize可能只影响服务接收的消息-这就是为什么我说先增加MaxBufferSize(和MaxBufferPoolSize),看看这是否已经解决了问题。好吧,然后再增加其他值!maxReceivedMessageSize、MaxStringContentLength、MaxArrayLength—当然,这是另一个选项—重要的不是大小,而是设置和发送数据表所需的时间。在这种情况下,您需要调整“sendTimeout”和可能的“receiveTimeout”-然后就可以了。WCF在设置操作时为您提供了极大的灵活性-并且可能您需要调整许多设置才能使一切正常-但至少您可以调整!其他系统不给你这个选项…不,对不起,仅仅根据我掌握的信息,我无法确定是什么问题。您得到了什么错误(如果有)?由于您可能只想流式传输响应(对吗?),您可以尝试transferMode=“StreamedResponse”您好,John,我有一些新发现,希望在这里分享。我在客户端和服务器端都增加了receiveTimeout/sendTimeout来定制基本的TpBinding行为,然后它就可以工作了!但当我将返回的行数增加到10000000时,即使我将超时值设置为1小时,也会发生相同的错误。有什么想法吗?你能在你这边重现同样的问题吗?我已经在事件日志中搜索了,与我在这里发布的错误异常信息相同。所以,没有更多的信息-(对于WCF跟踪,您的意思是?另外,如果您返回10000000行,那么您需要使用流式处理。我打赌您的服务内存不足,试图一次性将所有10000000行XML存储到内存中。@George2:查看中的许多注释,您会明白为什么我希望您花两分钟访问msdn.microsoft.com,并在搜索框中键入“wcf流”,然后单击“搜索”。如果在两分钟内没有找到要查找的内容,请单击c