【问题标题】:Configuring a WCF service binding in code在代码中配置 WCF 服务绑定
【发布时间】:2012-12-23 16:44:13
【问题描述】:

我有一个使用代码创建的自托管 Web 服务:

protected void StartService(Type serviceType, Type implementedContract, string serviceDescription)
{
    Uri addressTcp = new Uri(_baseAddressTcp + serviceDescription);
    ServiceHost selfHost = new ServiceHost(serviceType, addressTcp);
    Globals.Tracer.GeneralTrace.TraceEvent(TraceEventType.Information, 0, "Starting service " + addressTcp.ToString());
    try
    {
        selfHost.AddServiceEndpoint(implementedContract, new NetTcpBinding(SecurityMode.None), "");

        ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
        selfHost.Description.Behaviors.Add(smb);
        System.ServiceModel.Channels.Binding binding = MetadataExchangeBindings.CreateMexTcpBinding();
        selfHost.AddServiceEndpoint(typeof(IMetadataExchange), binding, "mex");
        selfHost.Open();

        ServiceInfo si = new ServiceInfo(serviceType, implementedContract, selfHost, serviceDescription);
        try
        {
            lock (_hostedServices)
            {
                _hostedServices.Add(serviceType, si);
            }
        }
        catch (ArgumentException)
        {
             //...
        }
    }
    catch (CommunicationException ce)
    {
        //...
        selfHost.Abort();
    }
}

这没问题,但是当我尝试发送大块数据时,出现以下异常:

错误:格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数 @@@ 时出错。 InnerException 消息是“反序列化 @@@ 类型的对象时出错。读取 XML 数据时已超出最大字符串内容长度配额 (8192)。可以通过更改创建 XML 阅读器时使用的 XmlDictionaryReaderQuotas 对象的 MaxStringContentLength 属性来增加此配额。有关详细信息,请参阅 InnerException。 at: at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)

解决方案似乎是将 MaxStringContentLength 属性添加到绑定。我了解如何在 Web.config (link) 中执行此操作:

...绑定名称="wsHttpBindingSettings" maxReceivedMessageSize="2147483647">

我正在寻找一种在代码中修改绑定的 maxReceivedMessageSize 的方法。对于我使用的绑定类型,这是否可能?

谢谢。

编辑: 在了解了更多信息(并在收到的回复的指导下)后,我理解了这个问题:我试图修改服务的 MEX 部分,该部分仅用于宣传它,请参阅link。 我应该修改 NetTcpBinding 的绑定(try 语句中的第一行)。 现在我的(工作)代码如下所示:

...
    try
    {
        //add the service itself

        NetTcpBinding servciceBinding = new NetTcpBinding(SecurityMode.None);
        servciceBinding.ReaderQuotas.MaxStringContentLength = 256 * 1024;
        servciceBinding.ReaderQuotas.MaxArrayLength = 256 * 1024;
        servciceBinding.ReaderQuotas.MaxBytesPerRead = 256 * 1024;
        selfHost.AddServiceEndpoint(implementedContract, servciceBinding, "");
...

【问题讨论】:

  • 实际上,您应该查看绑定下的 <ReaderQuotas> 子元素 - 这就是 MaxStringContentLength 设置所在的位置......

标签: c# .net wcf


【解决方案1】:

您需要查看绑定下的 <ReaderQuotas> 子元素 - 这就是 MaxStringContentLength 设置所在的位置......

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="test">
          <readerQuotas maxStringContentLength="65535" />   <== here's that property!
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>

在代码中,你可以这样设置:

NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
binding.ReaderQuotas.MaxStringContentLength = 65535;

然后将此绑定用于服务端点...

selfHost.AddServiceEndpoint(implementedContract, binding, "");

【讨论】:

    【解决方案2】:
    var binding = new NetTcpBinding(SecurityMode.None);
    binding.MaxReceivedMessageSize = 2147483647;//this your maxReceivedMessageSize="2147483647"
    binding.ReaderQuotas.MaxStringContentLength = 2147483647;//this property need set by exception
    selfHost.AddServiceEndpoint(implementedContract, binding , "");
    

    【讨论】:

      【解决方案3】:

      我的解决方案是托管 Silverlight 客户端的 ASP.NET 站点,其中服务客户端引用位于可移植项目中。服务通过带有用户名身份验证的 HTTPS 运行。

      我在通过 WCF 发送图片 (byte[]) 时遇到了一些问题,但解决如下:

      我的网站的 web.config 有一个绑定(在 system.serviceModel 下),定义如下:

      <bindings>
        <customBinding>
          <binding name="WcfServiceBinding" receiveTimeout="00:10:00" sendTimeout="00:10:00" closeTimeout="00:10:00" openTimeout="00:10:00">
            <security authenticationMode="UserNameOverTransport" />
            <binaryMessageEncoding></binaryMessageEncoding>
            <httpsTransport maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" keepAliveEnabled="true" />
          </binding>
        </customBinding>
      </bindings>
      

      在我的 portable 库中,我获得了 WCF 服务引用并在代码中定义我的绑定:

      public static CustomBinding ServiceBinding
      {
          get
          {
              if (binding != null)
              {
                  return binding;
              }
      
              binding = new CustomBinding
              {
                  CloseTimeout = new TimeSpan(0, 2, 0),
                  ReceiveTimeout = new TimeSpan(0, 3, 0),
                  SendTimeout = new TimeSpan(0, 5, 0)
              };
      
              var ssbe = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
              binding.Elements.Add(ssbe);
              binding.Elements.Add(new BinaryMessageEncodingBindingElement());
              binding.Elements.Add(
                  new HttpsTransportBindingElement { MaxReceivedMessageSize = 2147483647, MaxBufferSize = 2147483647 });
      
              return binding;
          }
      }
      

      为了创建我的客户端,我得到了静态绑定定义:

      private static DataServiceClient CreateClient()
      {
          var proxy = new DataServiceClient(ServiceUtility.ServiceBinding, ServiceUtility.DataServiceAddress);
          proxy.ClientCredentials.SetCredentials();
          return proxy;
      }
      

      对我来说很好用。祝你好运。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-18
        • 1970-01-01
        • 2012-11-18
        • 2016-10-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多