【问题标题】:Unable to set ReaderQuotas for BasicHttpBinding generated in code无法为代码中生成的 BasicHttpBinding 设置 ReaderQuotas
【发布时间】:2011-07-12 21:18:40
【问题描述】:

我有一个项目要求生成一个没有依赖关系的单个可执行文件,该文件将根据传递给它的命令行参数自动将数据提交到 WCF 服务。因此,我无法在 App.config 文件中配置 WCF 绑定和配额,因此我在代码中生成了一个 BasicHttpBinding 以在标注 WCF 客户端对象时使用。

但是,WCF 服务接受的二进制数据用于一个相对较小的 Excel 电子表格,最终大小约为 30kb,因此绑定的ReaderQuotas 的默认配置设置不合适。但是,我尝试将它们的代码增加到 1MB,但每次调用该服务时都失败了。

我尝试通过以下两种方式设置绑定,首先是在构造函数本身中:

Private theBinding As New BasicHttpBinding With {
    .SendTimeout = TimeSpan.FromMinutes(1),
    .OpenTimeout = TimeSpan.FromMinutes(1),
    .CloseTimeout = TimeSpan.FromMinutes(1),
    .ReceiveTimeout = TimeSpan.FromMinutes(10),
    .AllowCookies = False,
    .BypassProxyOnLocal = False,
    .HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
    .MessageEncoding = WSMessageEncoding.Text,
    .TransferMode = TransferMode.Buffered,
    .UseDefaultWebProxy = True,
    .MaxBufferSize = 1048576,
    .MaxReceivedMessageSize = 1048576,
    .ReaderQuotas = New XmlDictionaryReaderQuotas With {
        .MaxDepth = 32,
        .MaxStringContentLength = 8192,
        .MaxArrayLength = 1048576,
        .MaxBytesPerRead = 4096,
        .MaxNameTableCharCount = 16384
    }
}

还可以通过删除上述代码中的ReaderQuotas 设置器并在表单加载时使用System.Reflection 将其设置为最大值。我意识到这种方法更适用于在配置文件中创建的绑定,因此通常是不可变的,但我认为尝试一下也无妨:

theBinding.GetType.GetProperty("ReaderQuotas").SetValue(theBinding, XmlDictionaryReaderQuotas.Max, Nothing)

使用 WCF 客户端构造函数的最终重载来确定 WCF 客户端的尺寸:

Using theClient As New WCFServiceClient(theBinding, theEndpoint)
    ...
End Using

但是,在调用 WCF 客户端时,我仍然收到以下异常:

System.ServiceModel.ProtocolException:格式化程序在尝试反序列化消息时抛出异常:出现错误 在尝试反序列化参数http://tempuri.org/:theObject 时。 InnerException 消息是“反序列化 RootNameSpace.ObjectType 类型的对象。最大数组长度 读取 XML 数据时已超出配额 (16384)。这个配额可以 通过更改 MaxArrayLength 属性来增加 创建 XML 阅读器时使用的 XmlDictionaryReaderQuotas 对象。 第 1 行,位置 46272.'。有关详细信息,请参阅 InnerException。

头是会议桌。在正确配置读者配额时,我真的可以使用一些指导来了解我可能在这里错过的内容。

【问题讨论】:

    标签: vb.net wcf wcf-binding


    【解决方案1】:

    检查您的服务的配置文件(如果有的话)或其使用的绑定设置。可能客户端发送消息正常,但服务拒绝它,因为它仍在使用默认值。

    【讨论】:

    • 这至少让我指出了正确的方向。不幸的是,一些关于细节的文档有点模糊和/或不完整/不准确。我很感激你抬起头来!用户应查看 my answer 了解实施细节。
    【解决方案2】:

    正如Tim 所建议的,此问题的解决方案是正确配置 IIS 服务端点以读取大型消息,而不仅仅是客户端。由于我没有遇到关于这样做的现成/准确/彻底的信息,因此我在这里为那些关注的人复制我的解决方案。

    首先,使用适当的阅读器配额设置配置基本 HTTP 绑定,如下所示:

    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="basicHttpBinding_IMyService" maxReceivedMessageSize="2147483647">
                    <readerQuotas maxDepth="32" maxArrayLength="2147483647" maxStringContentLength="2147483647"
                                  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                </binding>
            </basicHttpBinding>
        </bindings>
    <system.serviceModel>
    

    要考虑的重要字段是readerQuotasmaxArrayLengthmaxStringcontentLength 属性的值以及bindingmaxReceivedMessageSize 属性的值。我已经将它们设置为最大值——我相信——在这个例子中,但在我的实际实现中,我选择了 1MB (1048576) 的值。设置您认为最适合您的服务的价值观。然后使用您刚刚生成的绑定配置为您的合约指定一个端点:

    <system.serviceModel>
        <services>
            <service>
                <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding_IMyService"
                          contract="RootNamespace.IMyService" />
            </service>
        </services>
    <system.serviceModel>
    

    请注意,在我的例子中,没有必要设置端点的地址。值得一提的是,我的目标是 .NET 4.0 框架,并在我的托管环境中使用 &lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true" /&gt; 启用了多个站点绑定。您的里程可能会有所不同。

    【讨论】:

    • 谢谢,解释得很好,似乎解决了我的问题。我认为这个级别的默认限制是 64KB,我在 SOAP 请求大约 78KB 时遇到了失败。
    猜你喜欢
    • 1970-01-01
    • 2015-01-03
    • 2012-08-15
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2015-04-24
    相关资源
    最近更新 更多