【问题标题】:Moving service configuration from the config to code将服务配置从配置移至代码
【发布时间】:2019-01-16 20:32:20
【问题描述】:

我的 app.config 中有以下配置:

<bindings>
  <customBinding>
    <binding name="myBinding">
      <textMessageEncoding messageVersion="Soap12"/>
      <httpTransport/>
    </binding>
  </customBinding>
  <wsHttpBinding>
    <binding name="myBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8">
      <security mode="Transport">
        <transport clientCredentialType="Windows"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="/../" binding="wsHttpBinding" bindingConfiguration="myBinding" contract="myContract" name="myName"/>
</client>

使用此配置,服务按预期工作。

由于多种原因,我无法在生产环境中使用 app.config 文件,因此我想改为在 c# 中定义绑定。我做了以下事情:

        var binding = new BasicHttpBinding();
        var address = new EndpointAddress(url);

        binding.Security = new BasicHttpSecurity() { Mode = BasicHttpSecurityMode.Transport };
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

        var client = new MyClient(binding, address);

这适用于第一部分,但随后因使用不正确的消息版本而失败。我可以看到这是在自定义绑定中定义的,但我不确定如何将此绑定转换为我的代码。我确实尝试了很多,但到目前为止还没有结果。

有人知道怎么做吗?

【问题讨论】:

  • 你能改进你的问题吗?我不明白。您想继续使用配置文件并在代码中使用它吗?
  • 更新了我的问题,希望现在更清楚了。
  • 谢谢。能不能也加一下错误信息?

标签: c# wcf


【解决方案1】:

我建议您利用 ConfigurationChannelFactory&lt;TChannel&gt; 类来配置您的客户端,使用来自 app.config 文件以外的源的 XML 配置(例如,从数据库、可执行文件中的资源或从其他一些自定义来源)。

恕我直言,XML 格式比使用代码构建的配置更易于阅读和维护。

为此,步骤如下:

  • 获取包含您的 XML 配置数据的字符串,例如:

    string configurationData = @"<configuration>
        <system.serviceModel>
        ...
        ";
    
  • 将其保存到临时文件:

    var tempFileName = Path.GetTempFileName();
    File.WriteAllText(tempFileName, configurationData);
    
  • 从临时文件生成System.Configuration.Configuration 对象:

    var filemap = new ExeConfigurationFileMap
    {
        ExeConfigFilename = tempFileName
    };
    var config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);
    
  • 从配置中创建一个ChannelFactory&lt;TChannel&gt;

    var channelFactory = new ConfigurationChannelFactory<TChannel>(endpointConfigurationName, config, remoteAddress);
    
  • 创建ChannelFactory&lt;TChannel&gt; 后,您可以删除临时文件。

【讨论】:

    【解决方案2】:

    您使用的是BasicHttpBinding 而不是CustomBinding

    你应该这样做:

    var binding = new CustomBinding();
    TextMessageEncodingBindingElement textBindingElement = new TextMessageEncodingBindingElement
    {
        MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None),
        WriteEncoding = System.Text.Encoding.UTF8,
        ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max
    };
    binding.Elements.Add(textBindingElement);
    

    但是,如果您使用的是 .net core,您可能会遇到问题,因为 GitHub 上有一个未解决的问题:https://github.com/dotnet/wcf/issues/2711

    【讨论】:

      【解决方案3】:

      看来您正在使用 wshttpbinding。 您可以试试下面的代码。请更改您的地址和合同。

        WSHttpBinding wsbinding = new WSHttpBinding();
              wsbinding.MaxBufferPoolSize = 2147483647;
              wsbinding.MaxReceivedMessageSize = 2147483647;
              wsbinding.MessageEncoding = WSMessageEncoding.Mtom;
              wsbinding.TextEncoding = Encoding.UTF8;
              wsbinding.Security.Mode = SecurityMode.Transport;
              wsbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
      
              using (ChannelFactory<ICalculatorService> channelFacoty = new ChannelFactory<ICalculatorService>(wsbinding, new EndpointAddress("http://localhost")))
              {
                  ICalculatorService cal = channelFacoty.CreateChannel();
                 Console.WriteLine( cal.Add(1, 3));
                  Console.Read();
              }
      

      【讨论】:

        【解决方案4】:

        试试 WebHttBinding:

        binding = new WebHttpBinding
        {
            TransferMode = TransferMode.Buffered,
            ReceiveTimeout = TimeSpan.FromMinutes(1),
            SendTimeout = TimeSpan.FromMinutes(1),
            MaxReceivedMessageSize = 2147483647,
            MaxBufferPoolSize = 2147483647,
            ReaderQuotas =
                {
                    MaxDepth = 2147483647,
                    MaxStringContentLength = 2147483647,
                    MaxArrayLength = 2147483647,
                    MaxBytesPerRead = 2147483647,
                    MaxNameTableCharCount = 2147483647
                },
            Security = new WebHttpSecurity()
            {
                Mode = WebHttpSecurityMode.Transport,
                Transport = new HttpTransportSecurity()
                {
                    ClientCredentialType = HttpClientCredentialType.Ntlm
                }
            }
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-23
          • 1970-01-01
          • 2021-12-19
          • 1970-01-01
          • 2019-01-18
          • 1970-01-01
          • 2020-07-30
          • 1970-01-01
          相关资源
          最近更新 更多