将服务配置从配置移动到代码
Moving service configuration from the config to code
我的 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);
这适用于第一部分,但随后因使用不正确的消息版本而失败。我可以看到这是在自定义绑定中定义的,但我不确定如何将此绑定转换为我的代码。我确实尝试了很多,但到目前为止还没有结果。
有人知道怎么做吗?
您正在使用 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 核心,您可能会遇到问题,因为 GitHub 上有一个未解决的问题:https://github.com/dotnet/wcf/issues/2711
我建议您利用 ConfigurationChannelFactory<TChannel>
class 使用来自 app.config 文件以外来源的 XML 配置来配置您的客户端(例如 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<TChannel>
:
var channelFactory = new ConfigurationChannelFactory<TChannel>(endpointConfigurationName, config, remoteAddress);
创建 ChannelFactory<TChannel>
后,您可以删除临时文件。
您似乎正在使用 wshttpbinding。
您可以尝试将代码 below.Please 更改为您的地址和合同。
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();
}
试试 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
}
}
};
我的 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);
这适用于第一部分,但随后因使用不正确的消息版本而失败。我可以看到这是在自定义绑定中定义的,但我不确定如何将此绑定转换为我的代码。我确实尝试了很多,但到目前为止还没有结果。
有人知道怎么做吗?
您正在使用 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 核心,您可能会遇到问题,因为 GitHub 上有一个未解决的问题:https://github.com/dotnet/wcf/issues/2711
我建议您利用 ConfigurationChannelFactory<TChannel>
class 使用来自 app.config 文件以外来源的 XML 配置来配置您的客户端(例如 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<TChannel>
:var channelFactory = new ConfigurationChannelFactory<TChannel>(endpointConfigurationName, config, remoteAddress);
创建
ChannelFactory<TChannel>
后,您可以删除临时文件。
您似乎正在使用 wshttpbinding。 您可以尝试将代码 below.Please 更改为您的地址和合同。
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();
}
试试 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
}
}
};