最大数组长度配额
我正在编写一个小的WCF / WPF应用程序来调整图像大小,但当我尝试从客户端发送一个大小为28K的图像到我的服务时,WCF给了我很大的痛苦。 当我发送较小的图像时,该服务正常工作。 我马上认为这是一个configuration问题,我已经通过绑定configuration浏览了关于MaxArrayLength属性的post。 我已经把客户端和服务器上的这些设置的限制提高到了最大值2147483647,但仍然出现以下错误:
格式化程序尝试反序列化消息时引发exception:尝试反序列化参数http://mywebsite.com/services/servicecontracts/2009/01:OriginalImage时出错。 InnerException消息是“反序列化System.Drawing.Imagetypes的对象时发生错误。 读取XML数据时,超出了最大数组长度限额(16384)。 这个配额可以通过改变创buildXML阅读器时使用的XmlDictionaryReaderQuotas对象的MaxArrayLength属性来增加。 请参阅InnerException获取更多细节。
我已经使我的客户端和服务器configuration相同,他们看起来像下面:服务器:
<system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_ImageResizerServiceContract" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647"> <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> <message clientCredentialType="Windows" /> </security> </binding> </netTcpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="ServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service name="LogoResizer.WCF.ServiceTypes.ImageResizerService" behaviorConfiguration="ServiceBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:900/mex/"/> <add baseAddress="net.tcp://localhost:9000/" /> </baseAddresses> </host> <endpoint binding="netTcpBinding" contract="LogoResizer.WCF.ServiceContracts.IImageResizerService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> </system.serviceModel>
和我的客户端configuration如下所示:
<system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_ImageResizerServiceContract" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647"> <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> <message clientCredentialType="Windows" /> </security> </binding> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://localhost:9000/" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ImageResizerServiceContract" contract="ImageResizerService.ImageResizerServiceContract" name="NetTcpBinding_ImageResizerServiceContract"> <identity> <userPrincipalName value="me@domain.com" /> </identity> </endpoint> </client> </system.serviceModel>
似乎不pipe我设置这些值,我仍然得到一个错误,说wcf不能序列化我的文件,因为它大于16384.任何想法?
更新: userPrincipalName标记中的电子邮件地址已被更改为我的隐私
我的坏 – 我忘记将我的绑定configuration应用到我的服务器端configuration中的端点。 服务器configuration应为:
<system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_ImageResizerServiceContract" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647"> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> <message clientCredentialType="Windows" /> </security> </binding> </netTcpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="ServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service name="LogoResizer.WCF.ServiceTypes.ImageResizerService" behaviorConfiguration="ServiceBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:900/mex/"/> <add baseAddress="net.tcp://localhost:9000/" /> </baseAddresses> </host> <endpoint bindingConfiguration="NetTcpBinding_ImageResizerServiceContract" binding="netTcpBinding" contract="LogoResizer.WCF.ServiceContracts.IImageResizerService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> </system.serviceModel>
注意bindConfiguration =“NetTcpBinding_ImageResizerServiceContract”已被添加到netTcp端点。 我的应用程序现在与更大的图像。 甜。
请在绑定中添加<readerQuotas>
。
这是上传和下载字节[]的主要问题,它解决了我的问题。
<basicHttpBinding> <binding name="ServicesBinding" transferMode="Streamed" maxBufferSize="200000000" maxReceivedMessageSize="200000000" messageEncoding="Text" receiveTimeout="00:10:00"> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> </binding> </basicHttpBinding>
我使用了Microsoft SDK SvcConfigEditor。 你有这个如果你使用Visual Studio(它有自己的版本)。 这也是一个免费下载。
在您的硬盘上(同时检查程序文件和程序文件(x86)):
C:\ Program Files(x86)\ Microsoft SDKs \ Windows \ v7.0A \ Bin \ NETFX 4.0 Tools \ SvcConfigEditor.exe
C:\ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Bin \ NETFX 4.0 Tools \ SvcConfigEditor.exe
如果您有多个Microsoft SDK安装,则使用哪个版本将取决于您正在开发的.NET版本。 该工具将抛出一个错误,让你知道你试图打开错误的版本下的.dll文件。
要使用该工具,请指向您的服务的.dll文件并让该工具完成繁重工作。 如果您的服务与服务交谈(代理服务),这特别有用。 此外,请记住,您可能需要为您的客户端(在应用程序)和服务器configuration(在Web服务)的configuration设置。
我错过了服务器端点上的configuration。 我必须做两件事情:
- 在我的服务器端configuration端点,使用SvcConfigEditorconfiguration
- 请记住在SvcConfigEditor工具中设置MaxArrayLength
另外,ASP.NET对这个值也是挑剔的,所以你可以尝试简化你的configuration绑定并closures它:
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
它的工作,以前显示net.tcp://myservice.com/Ac_Service.svc/mex浏览wcf服务时的参考,但现在它是http://myservice.com/Ac_Service.svc?wsdl
将来也能工作,没有任何问题。