我为我现在的雇主开发了一个客户端/服务器应用程序,其中一个要求是客户端部分作为 DLL 分发。由于 DLL 不“执行”dllName.dll.config 文件,因此我需要将配置移动到代码中。我已尽我所能做到这一点,但我现在遇到了这个异常(exception);
The X.509 certificate CN=ComputerName chain building failed.
The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. An internal certificate chaining error has occurred.
我已经用 google 搜索过,并以其他方式搜索过这个问题的解决方案,但到目前为止,我找不到任何对我所见过的各种接近但不是真的解决方案有足够清晰解释的内容。
无论如何,My LocalStore 中有一个证书,但它实际上仅供服务器使用(目前正在同一个 XP Pro 机器上测试客户端和服务器),至少,据我所知是这样。 (对 WCF 还是很陌生)(请注意下面的客户端配置文件如何不获取或以其他方式向客户端指出上述证书。
客户端的 app.config 如下所示,通过我们的测试 EXE 运行良好,其中包含此配置文件的部分。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="MyTcpBinding_IFileXferService"
receiveTimeout="02:00:00"
sendTimeout="02:00:00"
transferMode="Streamed"
maxBufferSize="65536"
maxReceivedMessageSize="2147483647">
<readerQuotas maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="65536" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientConfigBehavior">
<dataContractSerializer maxItemsInObjectGraph="6553600" />
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint name="ClientConfig"
binding="netTcpBinding"
bindingConfiguration="MyTcpBinding_IFileXferService"
behaviorConfiguration="ClientConfigBehavior"
contract="ServiceRefs.IFileXferService" />
</client>
</system.serviceModel>
</configuration>
但现在我已经将配置信息移到代码中(这样 DLL 可以在没有 .config 文件的情况下分发),我再次遇到上述异常。 (顺便说一句,如果我们发现给定的设置需要更改,我可以将其添加到我们自己的 xml 配置文件中。)
用于替换上述配置的代码如下所示:
...
netTcpBinding = new NetTcpBinding();
endpointAddr = new EndpointAddress(HostURI);
updateMaxItemsBehavior(); // method below this snippet
TimeSpan tsTwoHours = new TimeSpan(2,0,0);
netTcpBinding.ReceiveTimeout = tsTwoHours;
netTcpBinding.SendTimeout = tsTwoHours;
netTcpBinding.TransferMode = TransferMode.Streamed;
netTcpBinding.MaxBufferSize = 65536;
netTcpBinding.MaxReceivedMessageSize = 2147483647;
netTcpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
netTcpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
netTcpBinding.ReaderQuotas.MaxBytesPerRead = 65536;
// double the 64k default
netTcpBinding.MaxBufferPoolSize = 131072;
netTcpBinding.Security.Mode = SecurityMode.Transport;
netTcpBinding.Security.Transport.ClientCredentialType =
TcpClientCredentialType.None;
// now to instantiate the service proxy client
svcClient = new FileXferServiceClient(netTcpBinding, endpointAddr);
我已经用这些接下来的位的各种组合尝试过这个,但不能 绕过该死的异常。
// Set the certificate for the client.
X509Certificate2 cert = new X509Certificate2();
svcClient.ClientCredentials.ClientCertificate.Certificate = cert;
//svcClient.ClientCredentials.ClientCertificate.SetCertificate(
// StoreLocation.LocalMachine,
// StoreName.My,
// X509FindType.FindByThumbprint,
// "ThumbprintThumbprintThumbprintThumbprint");
// here's this
//
private void updateMaxItemsBehavior()
{
svcEndpoint = new ServiceEndpoint(
new ContractDescription("IFileXferService"));
foreach (OperationDescription operation in
svcEndpoint.Contract.Operations)
{
operation.Behaviors
.Find<DataContractSerializerOperationBehavior>()
.MaxItemsInObjectGraph = 6553600;
}
}
总而言之,我们的测试 Winforms 应用程序(以及我们的 WCF 应用程序的客户端)在 wfappname.exe.config 文件中的配置设置下运行良好,但现在我已尝试将其全部移动到代码中,它显然需要证书。我想我真正希望的是“我如何在代码中复制上面的 app.config,以便我的 WCF 客户端不需要 app.config。”
谁能帮我解决这个问题? (我会成为你最好的 friend !); )
谢谢, 斯科特
最佳答案
我觉得你是个男人。
我不喜欢这样的想法,例如,当 WCF 服务部署到 IIS 中时,我必须将 .config 内容嵌入到 web.config 中,或者在以其他方式托管时转换 .config 并嵌入到代码中.
我解决这个问题的方法是使用覆盖默认 ApplyConfiguration() 的自定义服务主机逻辑。在服务端,它允许 WCF DLL 在 dllname.dll.config(或任何地方)中查找其配置。
是all explained here .该信息也在 this answer on Stackoverflow 中重复。 .
您使用的是 WCF 客户端,因此您需要覆盖 ApplyConfiguration() method in a custom ChannelFactory .这是描述here .在同一篇论坛帖子中,描述了一种替代技术,您可以在其中覆盖 CreateDescription()并指定另一个 .config 文件路径。这些方法非常相似;两者都应该在 WCF 客户端中工作。
您还可以考虑将 .config 作为资源嵌入到 .dll 中。这样,您仍然有一个单文件分发(dll),但您可以使用 xml 配置语法来指定所有内容。在构建时,将 .config 文件嵌入到 DLL 中。在您的自定义 ApplyConfiguration() 运行时,您必须调用 Assembly.GetManifestResourceStream(); ,传递字符串“dllname.dll.config”以获取包含配置信息的只读流。
如果您希望允许用户覆盖嵌入式配置,那么您可以将该智能引入您自己的 ApplyConfiguration() 实现中。可能先寻找文件系统文件;如果它不存在,则回退到嵌入式 .config 文件。
这个答案并没有真正告诉您如何将配置设置移动到代码中,因为我认为这是一个令人发指的想法。但也许它无论如何都能解决您的问题。
关于c# - 需要如何帮助将 system.serviceModel 配置部分移动到我的代码中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4110178/