Нужно Как помочь перенести раздел конфигурации system.serviceModel в мой код - PullRequest
3 голосов
/ 06 ноября 2010

Я разработал приложение клиент / сервер для моего текущего работодателя, и одно из требований заключается в том, чтобы клиентская часть распространялась в виде 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 в коде, чтобы app.config не требовался моим клиентом WCF».

Может кто-нибудь помочь мне с этим? (Я буду твоим лучшим другом!); )

Спасибо, Скотт

1 Ответ

3 голосов
/ 07 ноября 2010

Я чувствую тебя, чувак.

Мне не нравится идея, что мне нужно встраивать материал .config в web.config, например, когда служба WCF развертывается в IIS, или переводить .config и встраивать в код при размещении другим способом ,

Чтобы обойти это, я использовал хост собственной службы, который переопределяет логику ApplyConfiguration () по умолчанию. На стороне службы он позволяет DLL-библиотеке WCF искать свою конфигурацию в dllname.dll.config (или в любом другом месте).

Здесь все объяснено . Эта информация также дублируется в этом ответе в Stackoverflow .

Вы используете клиент WCF, поэтому вам необходимо переопределить метод ApplyConfiguration () в пользовательском ChannelFactory . Это описано здесь . В этом же сообщении на форуме описан альтернативный метод, в котором вы переопределяете CreateDescription () и указываете альтернативный путь к файлу .config. Эти подходы очень похожи; либо должен работать в клиенте WCF.

Вы можете также рассмотреть возможность встраивания .config в качестве ресурса, встроенного в .dll. Таким образом, у вас все еще есть дистрибутив с одним файлом (dll), но вы можете использовать синтаксис xml config для указания всего. Во время сборки вставьте файл .config в DLL. Во время выполнения внутри вашей пользовательской ApplyConfiguration () вам нужно будет вызвать Assembly.GetManifestResourceStream (); , передавая строку "dllname.dll.config", чтобы получить поток только для чтения, который содержит информацию о конфигурации.

Если вы хотите разрешить пользователю переопределять встроенную конфигурацию, вы можете внедрить этот интеллект в вашу собственную реализацию ApplyConfiguration (). Вероятно, сначала найдите файл файловой системы; если его нет, то откат к встроенному файлу .config.

Этот ответ на самом деле не говорит вам, как перенести настройки конфигурации в код, потому что я думаю, что это отвратительная идея. Но, возможно, это решит твою проблему в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...