Question

WPF + .NET 4.5 + ClickOnce deployment - Have been going through to solve this problem of how to set the connection string in the app.config file when the application gets deployed on the client machine but seems like there is NO WAY! to get this resolved.

If this question has been asked prior and has been answered previously, please provide us with necessary links - Thanks in advance

OK, here it goes, we have developed an WPF application which connects to our SQLExpress DB and on the development application machine we use the connection string which works great. We have been using the connection string in the app.config file (currently its not encrypted, but going forward that will be encrypted). We are packing our application using Clickonce deployment technique to ship to our client which is also fine till the point we handover to our client.

At the client side, we need to change the DB connection string and this need to be applied in app.config. But when package this using VStudio it takes the connection string which has been set during our development stage, but if we set the clients connection string and then pack it, it works OK - We understand this. We also understand when using clickonce to deploy the application, the application get installed under "*%Appdata%\local\apps\2.0*". Its really hard to search the respective folder under the above path and then set the connection string app.config.

Is there any other way to have this sorted out of using a connection string issue? Also another point is we are using entity framework and very often we use connection string from app.config to do the necessary process.

One of the means what we have thought is, to use a external file for storing the connection string and pass it according. But the challenge is when the entity framework calls are being called.

Any suggestion is highly appreciated.

Was it helpful?

Solution

we had the same issue with one of our apps. We solved it as follows:

  1. Add Settings file into your project, and add MyConnectionString string property into it
  2. When app starts for the first time - display "Please enter your connection string" form - and let user enter his connection string. Verify it's valid and then save it into settings:

like this:

MyApp.MySettings.MyConnectionString= cs;
MyApp.MySettings.Save();

and then you can build connection string in the code as described in this How to: Build an EntityConnection Connection String

the benefit of using "Settings" file is that the framework takes care of saving/persisting it etc, and you have strongly-type code support as well.

Regarding encryption - you can encrypt it before saving into settings file, and decrypt when reading. It's straightforward I think.

OTHER TIPS

I have used the app config to pick which service endpoint to consume, so I think this is pretty similar:

App.config

<add key="DEBUGServiceEndpoint" value="http://localhost:4398/Service.svc" />
<add key="DEVServiceEndpoint" value="http://dev/Service/Service.svc" />
<add key="TESTServiceEndpoint" value="http://testws/Service/Service.svc" />
<add key="PRODServiceEndpoint" value="http://ws/Service/Service.svc" />

And then use compiler directives to pick which string to use:

private string ServiceEndpoint
{
    get
    {
        #if DEV
            return ConfigurationManager.AppSettings["DEVServiceEndpoint"];
        #elif DEBUG
            return ConfigurationManager.AppSettings["DEBUGServiceEndpoint"];
        #elif TEST
            return ConfigurationManager.AppSettings["TESTServiceEndpoint"];
        #elif PRODUCTION
            return ConfigurationManager.AppSettings["PRODServiceEndpoint"];
         #endif
        }
}

In your case this would look something like this:

App.Config

<connectionStrings>
  <add name="Dev" connectionString="stuff" providerName="System.Data.SqlClient" />
  <add name="Test" connectionString="stuff" providerName="System.Data.SqlClient" />
  <add name="Prod" connectionString="stuff" providerName="System.Data.SqlClient" />
</connectionStrings>

Connection String in code:

    private string ConnectionString
    {
        get
        {
            #if DEV
            return ConfigurationManager.ConnectionStrings["Dev"].ConnectionString;
           #elif DEBUG
            return ConfigurationManager.ConnectionStrings["Dev"].ConnectionString;
           #elif TEST
            return ConfigurationManager.ConnectionStrings["Test"].ConnectionString;
           #elif PRODUCTION
            return ConfigurationManager.ConnectionStrings["Prod"].ConnectionString;
           #endif
        }
    }

Here is a way to update a connection string in your app.config via ClickOnce. Place this code when starting your application and before using the value from app.config:

UpdateCheckInfo info = null; //optional if(info.UpdateAvailable)
if (ApplicationDeployment.IsNetworkDeployed)
{
    
    ApplicationDeployment deployment = ApplicationDeployment.CurrentDeployment;
    string configPath = Application.ExecutablePath + ".config";
    if (deployment.IsFirstRun)
    {
        var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
        
        //example for a connectionstring you want to deploy while using your own connectionstring for developing in your own App.config
        connectionStringsSection.ConnectionStrings["ConnectionString"].ConnectionString = @"Integrated Security=SSPI;Pooling=true;Data Source=sqlServer_here;Initial Catalog=db_here";
        config.Save();
        ConfigurationManager.RefreshSection("connectionStrings");
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top