Well, sounds like there's two questions here:
- How to get app.config to update during runtime (which is possible, but isn't automatic); and,
- How to dynamically set bindings and endpoints at runtime based upon app.config settings.
For updating your app.config at runtime, call RefreshSection
. So you would probably want to hook up that call to the client button click event.
ConfigurationManager.RefreshSection("appSettings");
Console.WriteLine(ConfigurationManager.AppSettings["foo"]);
For dynamically setting your binding and endpoint information at runtime, that's definitely possible. I put a quick example together based on the MSDN Calculator Service examples. (I used BasicHttpBinding instead of WSHttpBinding just to keep it simple.) UPDATE Here's the only change I made to the example service:
// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new BasicHttpBinding(),
"CalculatorService");
The steps I took were:
- Create the service from the MSDN code sample and run it (so that the service endpoint was listening);
- Created a basic C# console application and added a service reference to my service so that it would create the client reference classes in my client console app. (It also created an app.config, but I'm not using any of those app.config settings it created.);
- Wrote the following code which sets up the Binding and EndpointAddress that my auto-generated client code will use to connect to the service:
*
static void Main(string[] args) {
//refresh the appSettings section
ConfigurationManager.RefreshSection("appSettings");
//this could come from app.configs appSettings (value = "http://localhost:8000/ServiceModelSamples/Service/CalculatorService")
Uri calcService = new Uri(ConfigurationManager.AppSettings["uri"]);
Binding calcBinding = new BasicHttpBinding(BasicHttpSecurityMode.None);
EndpointAddress calcEndpoint = new EndpointAddress(calcService.AbsoluteUri);
CalculatorClient calcClient = new CalculatorClient(calcBinding, calcEndpoint);
double sum = calcClient.Add(10, 20);
double difference = calcClient.Subtract(sum, 10);
Console.WriteLine("10 + 20 = {0}", sum.ToString());
Console.WriteLine("{0} - 10 = {1}", sum.ToString(), difference.ToString());
Console.ReadLine();
}
That should do it. So you can make the parameters to the Binding and EndpointAddress constructors read in from your configuration file (or user entry), and you can set additional Binding and EndpointAddress properties as you see fit.
Hopefully this helps. Let me know if there are additional questions and I'll update my answer accordingly.
UPDATE 2 (now with WSHttpBinding!!)
I updated this to include using WSHttpBinding (with message level security) as a second example. There's a lot of different ways to handle security with WCF, and MSDN has a nice guide on configuring your security accordingly based upon your scenario. Here's the link to that page.
So my updated example is basically the same as above, except the client creates a WSHttpBinding instead of BasicHttpBinding, and specifies Message level security as the SecurityMode.
static void Main(string[] args)
{
//refresh the appSettings section
ConfigurationManager.RefreshSection("appSettings");
//this could come from app.configs appSettings (value = "http://localhost:8000/ServiceModelSamples/Service/CalculatorService")
Uri calcService = new Uri(ConfigurationManager.AppSettings["uri"]);
//create the WsHttpBinding and set some security settings for the transport...
WSHttpBinding calcBinding = new WSHttpBinding(SecurityMode.Message);
EndpointAddress calcEndpoint = new EndpointAddress(calcService.AbsoluteUri);
CalculatorClient calcClient = new CalculatorClient(calcBinding, calcEndpoint);
double sum = calcClient.Add(10, 20);
double difference = calcClient.Subtract(sum, 10);
Console.WriteLine("10 + 20 = {0}", sum.ToString());
Console.WriteLine("{0} - 10 = {1}", sum.ToString(), difference.ToString());
Console.ReadLine();
}
The only difference I made on the server was that I specified WSHttpBinding when adding my service endpoint. Again, I chose the binding defaults, but that MSDN link above will describe how to configure the server based on your security needs.
// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
I hope this helps! Just remember that anything you can do in WCF configuration you can do in code. There's a 1:1 relationship between configuration settings and code (basically, everything in configuration translates to some WCF class that you can use).
Good luck! Let me know if there are other questions.