需要如何帮助将 system.serviceModel 配置部分移动到我的代码中

Posted

技术标签:

【中文标题】需要如何帮助将 system.serviceModel 配置部分移动到我的代码中【英文标题】:Need How To help moving system.serviceModel config section into my code 【发布时间】:2011-05-05 20:11:56 【问题描述】:

我为我现在的雇主开发了一个客户端/服务器应用程序,其中一个要求是客户端部分作为 DLL 分发。由于 DLL 不会“执行”dllName.dll.config 文件,因此我需要将配置移动到代码中。我已经尽我所能做到了,但我现在遇到了这个例外;

X.509 证书 CN=ComputerName 链构建失败。 使用的证书具有无法 得到验证。更换证书或更改 certificateValidationMode。 发生内部证书链接错误。

我已经用谷歌搜索过,或者到处搜索解决这个问题,但到目前为止,我找不到任何对我见过的各种接近但不是真的解决方案的足够清晰的解释。

无论如何,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。”

谁能帮我解决这个问题? (我会成为你最好的朋友!); )

谢谢, 斯科特

【问题讨论】:

【参考方案1】:

我觉得你是男人。

我不喜欢当 WCF 服务部署到 IIS 时必须将 .config 内容嵌入到 web.config 中的想法,或者在以其他方式托管时翻译 .config 并嵌入到代码中.

我解决它的方法是使用自定义服务主机来覆盖默认的ApplyConfiguration() 逻辑。它允许在服务端,WCF DLL 在 dllname.dll.config(或任何地方,实际上)中查找其配置。

它是all explained here。该信息也在this answer on *** 中重复。

您正在使用 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 文件。

这个答案并没有真正告诉你如何将配置设置移动到代码中,因为我认为这是一个令人发指的想法。但也许它无论如何都能解决你的问题。

【讨论】:

这看起来很有希望,我正在尝试从“...使用 WCF 客户端,因此您需要覆盖自定义 ChannelFactory 中的 ApplyConfiguration() 方法”中实现代码。现在,但我意识到,我的客户端代理(通过添加服务引用生成)继承自 ClientBase,而不是通道工厂。我只是搜索了有关如何 .. 执行代码正在执行的操作的信息,但是从 ClientBase 继承并且没有看到任何明显的内容。你有没有机会知道另一篇解释我如何做到这一点的文章? (谢谢!!!) 我看到您的答案已被编辑,但我不知道发生了什么变化。你能告诉我编辑了什么吗?再次感谢。 我刚刚添加了指向 CreateDescription 的链接。在使用从“添加服务参考”生成的代理时,仍在研究如何进行自定义配置位置。我确信这是可能的;只是方式问题。 啊,好的。我自己调查了一下,找不到一个直接的答案。这么多 MS 的对象都有挂钩、子类或其他方法,如果不可能,我会感到震惊,但是,是的,找出 HOW 显然是诀窍! (再次感谢!)

以上是关于需要如何帮助将 system.serviceModel 配置部分移动到我的代码中的主要内容,如果未能解决你的问题,请参考以下文章

我需要帮助弄清楚如何将 getline 放入 presentStringPrompt 以摆脱重复代码

需要如何帮助将 system.serviceModel 配置部分移动到我的代码中

我需要将 Array 转换为 ArrayList 帮助,不知道该怎么做? [复制]

在将数据聚合到视图中需要帮助 (SQL Server)

在 CvSVM 上需要帮助

需要帮助将代码从 jQuery 调整为 Angular