简体   繁体   English

在代码中配置WCF服务绑定

[英]Configuring a WCF service binding in code

I have a self hosted web service that is created in code: 我有一个用代码创建的自托管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();
    }
}

This works ok, but when I try to send large chunks of data I get the following exception: 这工作正常,但是当我尝试发送大块数据时,我得到以下异常:

Error: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter @@@ . 错误:格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数@@@时出错。 The InnerException message was 'There was an error deserializing the object of type @@@. InnerException消息是'反序列化@@@类型的对象时出错。 The maximum string content length quota (8192) has been exceeded while reading XML data. 读取XML数据时已超出最大字符串内容长度配额(8192)。 This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader.'. 通过更改创建XML阅读器时使用的XmlDictionaryReaderQuotas对象的MaxStringContentLength属性,可以增加此配额。 Please see InnerException for more details. 有关更多详细信息,请参阅InnerException。 at: at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) at:at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation,ProxyRpc&rpc)

The solution appears to be adding MaxStringContentLength property to the binding. 解决方案似乎是将MaxStringContentLength属性添加到绑定。 I understand how to do it in the Web.config ( link ): 我了解如何在Web.config( 链接 )中执行此操作:

... binding name="wsHttpBindingSettings" maxReceivedMessageSize="2147483647"> ... binding name =“wsHttpBindingSettings”maxReceivedMessageSize =“2147483647”>

I am looking for a way of modifying the binding's maxReceivedMessageSize in code. 我正在寻找一种在代码中修改绑定的maxReceivedMessageSize的方法。 Is that even possible with the type of binding that I am using? 我使用的绑定类型甚至可能吗?

Thanks. 谢谢。

Edit: After learning some more (and with the guidance of the responses I received) I understand the problem: I was trying to modify the MEX part of the service, which is only used to advertise it, see link . 编辑:在学习了一些之后(并且在我收到的回复的指导下)我理解了问题:我试图修改服务的MEX部分,它只用于做广告,见链接 I should have modified the binding of the NetTcpBinding (first line in the try statement). 我应该修改NetTcpBinding的绑定(try语句中的第一行)。 now my (working) code looks like this: 现在我的(工作)代码如下所示:

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

You need to look at the <ReaderQuotas> subelement under your binding - that's where the MaxStringContentLength setting lives.... 你需要查看绑定下的<ReaderQuotas>子元素 - 这是MaxStringContentLength设置所在的位置....

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

In code, you can set it like this: 在代码中,您可以像这样设置:

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

and then use this binding for the service endpoint ... 然后将此绑定用于服务端点...

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

My solution is an ASP.NET site hosting an Silverlight client, where the service client reference is in a Portable project. 我的解决方案是一个托管Silverlight客户端的ASP.NET站点,其中服务客户端引用位于Portable项目中。 Services run over HTTPS with username authentication. 服务使用用户名验证通过HTTPS运行。

I ran into some problems when sending a picture (byte[]) over WCF, but resolved it as following: 我在WCF上发送图片(byte [])时遇到了一些问题,但解决方法如下:

My web site's web.config has an binding (under system.serviceModel) defined as such: 我的网站的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>

In my portable lib I got a WCF service reference and define my binding in code as such: 在我的便携式 lib中,我得到了一个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;
    }
}

To create my client I get the static binding definition: 要创建我的客户端,我得到静态绑定定义:

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

Works great for me. 对我来说很棒。 Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM