Как программно изменить настройку адреса конечной точки WCF app.config?

Я хотел бы программно изменить файл app.config, чтобы указать, какая конечная точка файла службы должна использоваться. Каков наилучший способ сделать это во время выполнения? Для справки:

     

Я думаю, что вы хотите поменять время исполнения версии вашего конфигурационного файла, если это так, создайте копию вашего файла конфигурации (также укажите ему соответствующее расширение, например .Debug или .Release), которое имеет правильные адреса (что дает вам отладочную версию и версию исполнения) и создать шаг postbuild, который копирует правильный файл в зависимости от типа сборки.

Ниже приведен пример события postbuild, которое я использовал в прошлом, которое переопределяет выходной файл с правильной версией (debug / runtime)

 copy "$(ProjectDir)ServiceReferences.ClientConfig.$(ConfigurationName)" "$(ProjectDir)ServiceReferences.ClientConfig" /Y 

где: $ (ProjectDir) – это каталог проекта, в котором находятся файлы конфигурации $ (ConfigurationName), это тип активной конфигурации конфигурации

EDIT: Пожалуйста, см. Ответ Marc для подробного объяснения того, как это сделать программно.

Это на стороне клиента?

Если это так, вам нужно создать экземпляр WsHttpBinding и EndpointAddress, а затем передать эти два в клиентский конструктор прокси, который принимает эти два параметра.

 // using System.ServiceModel; WSHttpBinding binding = new WSHttpBinding(); EndpointAddress endpoint = new EndpointAddress(new Uri("http://localhost:9000/MyService")); MyServiceClient client = new MyServiceClient(binding, endpoint); 

Если это на стороне сервера, вам необходимо программно создать свой собственный экземпляр ServiceHost и добавить к нему соответствующие конечные точки обслуживания.

 ServiceHost svcHost = new ServiceHost(typeof(MyService), null); svcHost.AddServiceEndpoint(typeof(IMyService), new WSHttpBinding(), "http://localhost:9000/MyService"); 

Конечно, вы можете иметь несколько конечных точек обслуживания, добавленных на ваш хост-службы. Как только вы закончите, вам нужно открыть хост службы, вызвав метод .Open ().

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

Например, вы можете легко:

                

(три разных имени, разные параметры, указав различные привязкиConfigurations), а затем просто выберите правильный, чтобы создать экземпляр вашего сервера (или клиентского прокси).

Но в обоих случаях – сервер и клиент – вы должны выбрать до фактического создания хоста службы или прокси-клиента. После их создания они неизменяемы – вы не можете настроить их, когда они запущены и работают.

Марк

Я использую следующий код для изменения адреса конечной точки в файле App.Config. Вы можете захотеть изменить или удалить пространство имен перед использованием.

 using System; using System.Xml; using System.Configuration; using System.Reflection; //... namespace Glenlough.Generations.SupervisorII { public class ConfigSettings { private static string NodePath = "//system.serviceModel//client//endpoint"; private ConfigSettings() { } public static string GetEndpointAddress() { return ConfigSettings.loadConfigDocument().SelectSingleNode(NodePath).Attributes["address"].Value; } public static void SaveEndpointAddress(string endpointAddress) { // load config document for current assembly XmlDocument doc = loadConfigDocument(); // retrieve appSettings node XmlNode node = doc.SelectSingleNode(NodePath); if (node == null) throw new InvalidOperationException("Error. Could not find endpoint node in config file."); try { // select the 'add' element that contains the key //XmlElement elem = (XmlElement)node.SelectSingleNode(string.Format("//add[@key='{0}']", key)); node.Attributes["address"].Value = endpointAddress; doc.Save(getConfigFilePath()); } catch( Exception e ) { throw e; } } public static XmlDocument loadConfigDocument() { XmlDocument doc = null; try { doc = new XmlDocument(); doc.Load(getConfigFilePath()); return doc; } catch (System.IO.FileNotFoundException e) { throw new Exception("No configuration file found.", e); } } private static string getConfigFilePath() { return Assembly.GetExecutingAssembly().Location + ".config"; } } } 
 SomeServiceClient client = new SomeServiceClient(); var endpointAddress = client.Endpoint.Address; //gets the default endpoint address EndpointAddressBuilder newEndpointAddress = new EndpointAddressBuilder(endpointAddress); newEndpointAddress.Uri = new Uri("net.tcp://serverName:8000/SomeServiceName/"); client = new SomeServiceClient("EndpointConfigurationName", newEndpointAddress.ToEndpointAddress()); 

Я сделал это так. Хорошо, что он все еще берет остальные настройки привязки конечной точки из конфигурации и просто заменяет URI .

этот короткий код работал для меня:

 Configuration wConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); ServiceModelSectionGroup wServiceSection = ServiceModelSectionGroup.GetSectionGroup(wConfig); ClientSection wClientSection = wServiceSection.Client; wClientSection.Endpoints[0].Address = ; wConfig.Save(); 

Конечно, вам нужно создать прокси-сервер ServiceClient ПОСЛЕ изменения конфигурации. Вам также необходимо обратиться к assemblyм System.Configuration и System.ServiceModel, чтобы сделать эту работу.

ура

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

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Reflection; namespace LobbyGuard.UI.Registration { public class ConfigSettings { private static string NodePath = "//system.serviceModel//client//endpoint"; private ConfigSettings() { } public static string GetEndpointAddress() { return ConfigSettings.loadConfigDocument().SelectSingleNode(NodePath).Attributes["address"].Value; } public static void SaveEndpointAddress(string endpointAddress) { // load config document for current assembly XmlDocument doc = loadConfigDocument(); // retrieve appSettings node XmlNodeList nodes = doc.SelectNodes(NodePath); foreach (XmlNode node in nodes) { if (node == null) throw new InvalidOperationException("Error. Could not find endpoint node in config file."); //If this isnt the node I want to change, look at the next one //Change this string to the name attribute of the node you want to change if (node.Attributes["name"].Value != "DataLocal_Endpoint1") { continue; } try { // select the 'add' element that contains the key //XmlElement elem = (XmlElement)node.SelectSingleNode(string.Format("//add[@key='{0}']", key)); node.Attributes["address"].Value = endpointAddress; doc.Save(getConfigFilePath()); break; } catch (Exception e) { throw e; } } } public static void SaveEndpointAddress(string endpointAddress, string ConfigPath, string endpointName) { // load config document for current assembly XmlDocument doc = loadConfigDocument(ConfigPath); // retrieve appSettings node XmlNodeList nodes = doc.SelectNodes(NodePath); foreach (XmlNode node in nodes) { if (node == null) throw new InvalidOperationException("Error. Could not find endpoint node in config file."); //If this isnt the node I want to change, look at the next one if (node.Attributes["name"].Value != endpointName) { continue; } try { // select the 'add' element that contains the key //XmlElement elem = (XmlElement)node.SelectSingleNode(string.Format("//add[@key='{0}']", key)); node.Attributes["address"].Value = endpointAddress; doc.Save(ConfigPath); break; } catch (Exception e) { throw e; } } } public static XmlDocument loadConfigDocument() { XmlDocument doc = null; try { doc = new XmlDocument(); doc.Load(getConfigFilePath()); return doc; } catch (System.IO.FileNotFoundException e) { throw new Exception("No configuration file found.", e); } } public static XmlDocument loadConfigDocument(string Path) { XmlDocument doc = null; try { doc = new XmlDocument(); doc.Load(Path); return doc; } catch (System.IO.FileNotFoundException e) { throw new Exception("No configuration file found.", e); } } private static string getConfigFilePath() { return Assembly.GetExecutingAssembly().Location + ".config"; } } 

}

Это самый короткий код, который можно использовать для обновления файла конфигурации приложения, даже если он не имеет определенного раздела конфигурации:

 void UpdateAppConfig(string param) { var doc = new XmlDocument(); doc.Load("YourExeName.exe.config"); XmlNodeList endpoints = doc.GetElementsByTagName("endpoint"); foreach (XmlNode item in endpoints) { var adressAttribute = item.Attributes["address"]; if (!ReferenceEquals(null, adressAttribute)) { adressAttribute.Value = string.Format("http://mydomain/{0}", param); } } doc.Save("YourExeName.exe.config"); } 
 MyServiceClient client = new MyServiceClient(binding, endpoint); client.Endpoint.Address = new EndpointAddress("net.tcp://localhost/webSrvHost/service.svc"); client.Endpoint.Binding = new NetTcpBinding() { Name = "yourTcpBindConfig", ReaderQuotas = XmlDictionaryReaderQuotas.Max, ListenBacklog = 40 } 

Очень легко изменить uri в конфигурации или информации привязки в config. Это то, что вы хотите?

Вы можете сделать это следующим образом:

  • Сохраните настройки в отдельном XML-файле и прочитайте его, когда вы создаете прокси для своей службы.

Например, я хочу изменить адрес конечной точки службы во время выполнения, поэтому у меня есть следующий файл ServiceEndpoint.xml .

          
  • Для чтения вашего xml:

      var doc = new XmlDocument(); doc.Load(FileTransferConstants.Constants.SERVICE_ENDPOINTS_XMLPATH); XmlNodeList endPoints = doc.SelectNodes("/Services/Service/Endpoints"); foreach (XmlNode endPoint in endPoints) { foreach (XmlNode child in endPoint) { if (child.Attributes["name"].Value.Equals("ep1")) { var adressAttribute = child.Attributes["address"]; if (!ReferenceEquals(null, adressAttribute)) { address = adressAttribute.Value; } } } } 
  • Затем загрузите файл web.config своего клиента во время выполнения и назначьте адрес конечной точки службы следующим образом:

      Configuration wConfig = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = @"C:\FileTransferWebsite\web.config" }, ConfigurationUserLevel.None); ServiceModelSectionGroup wServiceSection = ServiceModelSectionGroup.GetSectionGroup(wConfig); ClientSection wClientSection = wServiceSection.Client; wClientSection.Endpoints[0].Address = new Uri(address); wConfig.Save(); 

Для чего мне стоит обновить порт и схему SSL для моего сервиса RESTFul. Это то, что я сделал. Извиняется, что это немного больше, чем оригинальный вопрос, но, надеюсь, он полезен кому-то.

 // Don't forget to add references to System.ServiceModel and System.ServiceModel.Web using System.ServiceModel; using System.ServiceModel.Configuration; var port = 1234; var isSsl = true; var scheme = isSsl ? "https" : "http"; var currAssembly = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; Configuration config = ConfigurationManager.OpenExeConfiguration(currAssembly); ServiceModelSectionGroup serviceModel = ServiceModelSectionGroup.GetSectionGroup(config); // Get the first endpoint in services. This is my RESTful service. var endp = serviceModel.Services.Services[0].Endpoints[0]; // Assign new values for endpoint UriBuilder b = new UriBuilder(endp.Address); b.Port = port; b.Scheme = scheme; endp.Address = b.Uri; // Adjust design time baseaddress endpoint var baseAddress = serviceModel.Services.Services[0].Host.BaseAddresses[0].BaseAddress; b = new UriBuilder(baseAddress); b.Port = port; b.Scheme = scheme; serviceModel.Services.Services[0].Host.BaseAddresses[0].BaseAddress = b.Uri.ToString(); // Setup the Transport security BindingsSection bindings = serviceModel.Bindings; WebHttpBindingCollectionElement x =(WebHttpBindingCollectionElement)bindings["webHttpBinding"]; WebHttpBindingElement y = (WebHttpBindingElement)x.ConfiguredBindings[0]; var e = y.Security; e.Mode = isSsl ? WebHttpSecurityMode.Transport : WebHttpSecurityMode.None; e.Transport.ClientCredentialType = HttpClientCredentialType.None; // Save changes config.Save(); 

посмотрите, размещаете ли вы клиентский раздел в правильном файле web.config. SharePoint имеет от 6 до 7 файлов конфигурации. http://msdn.microsoft.com/en-us/library/office/ms460914(v=office.14).aspx ( http://msdn.microsoft.com/en-us/library/office/ms460914%28v = office.14% 29.aspx )

Отправьте это, вы можете просто попробовать

ServiceClient client = new ServiceClient("ServiceSOAP");

Interesting Posts

Content-Disposition: Каковы различия между «inline» и «attachment»?

Будет ли мой ноутбук в порядке с этим другим зарядным устройством для ноутбука?

Chrome 33 показывает уродливые, блочные, пиксельные шрифты в Linux

Как получить доступ к графическому интерфейсу моего модема, когда он находится в режиме моста?

Почему Java 8 необязательно использовать в аргументах

Контролировать использование полосы пропускания каждого компьютера в сети

Rails 3 devise, current_user недоступен в модели?

Выполнение плагинов не покрывается конфигурацией жизненного цикла (JBossas 7 EAR archetype)

Пакетные файлы для кодирования

std :: map значение по умолчанию для встроенного типа

Каков правильный способ обмена результатами сетевого звонка с угловым Http в RxJs 5?

Как клонировать в непустой каталог?

Ошибка разрешения хранилища в Marshmallow

Я нашел два USB-накопителя на земле. Что теперь?

На локальном хосте, как мне выбрать номер порта?

Давайте будем гением компьютера.