How to programmatically change the WCF endpoint address setting app.config?

I would like to programmatically modify the app.config file to indicate which endpoint of the service file should be used. What is the best way to do this at runtime? For reference:

<endpoint address="http://mydomain/MyService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IASRService" contract="ASRService.IASRService" name="WSHttpBinding_IASRService"> <identity> <dns value="localhost" /> </identity> </endpoint> 
+49
c # wcf configuration-files app-config
Jun 08 '09 at 18:45
source share
11 answers

I think you want to change the execution time of the version of your configuration file, if so, create a copy of your configuration file (also indicate the corresponding extension, for example. Debug or .Release), which shows the correct addresses (which gives you the debug version and version of execution) and create a postbuild step that copies the correct file depending on the type of assembly.

Here is an example postbuild event that I used in the past that overrides the output file with the correct version (debug / runtime)

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

where: $ (ProjectDir) is the project directory where the configuration files are located $ (ConfigurationName) is the type of active configuration configuration

EDIT: See Marc's answer for a detailed explanation of how to do this programmatically.

+2
Jun 08 '09 at 18:59
source share

Is it on the client side?

If so, you need to instantiate WsHttpBinding and EndpointAddress, and then pass the two to the client proxy constructor, which takes these two as parameters.

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

If this is server-side, you need to programmatically create your own instance of ServiceHost and add the appropriate service endpoints to it.

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

Of course, you can have several service endpoints added to your host service. Once you're done, you need to open the service host by calling the .Open () method.

If you want to be able to dynamically - at run time - select which configuration to use, you can define several configurations, each with a unique name, and then call the appropriate constructor (for your service host or your proxy client) with the configuration name that you want to use.

eg. you can easily:

 <endpoint address="http://mydomain/MyService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IASRService" contract="ASRService.IASRService" name="WSHttpBinding_IASRService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="https://mydomain/MyService2.svc" binding="wsHttpBinding" bindingConfiguration="SecureHttpBinding_IASRService" contract="ASRService.IASRService" name="SecureWSHttpBinding_IASRService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="net.tcp://mydomain/MyService3.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IASRService" contract="ASRService.IASRService" name="NetTcpBinding_IASRService"> <identity> <dns value="localhost" /> </identity> </endpoint> 

(three different names, different parameters, specifying different Configurations bindings), and then simply select the correct one to create an instance of your server (or client proxy).

But in both cases - the server and the client - you must choose before actually creating the service host or proxy client. Once created, they are immutable - you cannot tune them after they run.

Mark

+94
Jun 08 '09 at 18:49
source share

I use the following code to change the endpoint address in the App.Config file. You may want to change or remove the namespace before use.

 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"; } } } 
+26
Jan 14 '10 at 22:37
source share
 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()); 

I did it like that. Good thing it still takes the rest of the endpoint binding settings from the configuration and just replaces the URI .

+11
Feb 20 '12 at 11:50
source share

this short code worked for me:

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

Of course, you need to create a ServiceClient proxy AFTER the configuration change. You also need to refer to the System.Configuration and System.ServiceModel assemblies to make this work.

Greetings

+4
Apr 08 '14 at 9:19
source share

I modified and extended the Malcolm Swaine code to change the specific node's name attribute, as well as change the external configuration file. Hope this helps.

 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"; } } 

}

+2
Sep 10 '12 at 19:33
source share

This is the shortest code you can use to update the application configuration file, even if it does not have a specific configuration section:

 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"); } 
+2
Dec 20
source share
 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 } 

It is very easy to change uri in configuration or binding information in config. Is this what you want?

+1
Dec 02 '13 at
source share

You can do it as follows:

  • Save your settings in a separate XML file and view it when creating a proxy server for your service.

For example, I want to change the address of a service endpoint at runtime, so I have the following ServiceEndpoint.xml file.

  <?xml version="1.0" encoding="utf-8" ?> <Services> <Service name="FileTransferService"> <Endpoints> <Endpoint name="ep1" address="http://localhost:8080/FileTransferService.svc" /> </Endpoints> </Service> </Services> 
  • To read your 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; } } } } 
  • Then get your client's web.config file at runtime and assign the service endpoint address as follows:

      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(); 
+1
Jan 27 '15 at 7:37
source share

Why should I upgrade the port and SSL scheme for my RESTFul service. This is what I did. Sorry this is a little more than the original question, but hopefully useful for someone.

 // 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(); 
+1
Aug 03 '15 at 10:23
source share

see if you place the client section in the correct web.config file. SharePoint has 6 to 7 configuration files. 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 )

Put it, you can just try

ServiceClient client = new ServiceClient("ServiceSOAP");

0
Dec 23 '14 at 13:37
source share



All Articles