在代码中配置WCF服务绑定

4

我有一个通过编程创建的自托管网络服务:

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 以获取更多详细信息。位于:在 System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) 处。
解决方案似乎是向绑定添加 MaxStringContentLength 属性。我知道如何在 Web.config 中实现它(link):
... binding name="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 设置所在的地方。 - marc_s
3个回答

2

您需要查看绑定下的<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, "");

1
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 , "");

0
我的解决方案是一个ASP.NET网站,托管了一个Silverlight客户端,其中服务客户端引用位于一个可移植项目中。服务在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>

在我的“便携式”库中,我有一个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;
}

对我来说很有效。祝你好运。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接