1

I'm developing an ASP.NET application using the MVC 5 framework. This application will ultimately be deployed on-premise. Therefore, users need to be able to install and configure the application before they can start using it. I need them to be able to specify things like the database name (MSSQL), the locations of various supporting services, and certain credentials like API keys for third-party services.

In a few MVC 5 applications I've used, these settings could be managed through a form. So I thought of creating a Configurations controller with GET and POST Edit actions. So the user can install the app, and then go to http://myServer/myApp/Config and specify the various settings there.

What I'm not sure about is where those settings would then be stored. Would it be the web.config file, or a settings.xml file, or the database?

Here's the strange thing... I already have a working solution with web.config that uses the below code:

public class ConfigController : Controller
{

    // GET: Config/Edit/5
    [HttpGet]
    public ActionResult Edit()
    {
        ViewBag.DatabaseServer = WebConfigurationManager.AppSettings["DatabaseServer"];
        ViewBag.DatabaseName = WebConfigurationManager.AppSettings["DatabaseName"];
        ViewBag.PusherClientID = WebConfigurationManager.AppSettings["ClientID"];
        ViewBag.PusherAPIKey = WebConfigurationManager.AppSettings["APIKey"];
        return View();
    }

    // POST: Config/Edit/5
    [HttpPost]
    public ActionResult Edit(FormCollection collection)
    {
        WebConfigurationManager.AppSettings.Set("DatabaseServer", collection.Get("databaseserver"));
        WebConfigurationManager.AppSettings.Set("DatabaseName", collection.Get("databasename"));
        WebConfigurationManager.AppSettings.Set("ClientID", collection.Get("pusherclientid"));
        WebConfigurationManager.AppSettings.Set("APIKey", collection.Get("pusherapikey"));

        return RedirectToAction("Edit");
    }
}

And my web.config file:

<appSettings>
    ...
    <add key="DatabaseServer" value="localhost\sqlexpress" />
    <add key="DatabaseName" value="MyDatabase" />
    <add key="ClientID" value="testID" />
    <add key="APIKey" value="testkey" />
</appSettings>

I can change these variables on a form on edit.cshtml and they persist fine. Two problems:

  1. I can't figure out where they go. I'm told they go in web.config but I checked both web.config files inside my app and none of them have the updated values. On the form, I update ClientID to "123" but in web.config it still says "testID" which is the original default value.
  2. I'm told that updating web.config will cause the app pool to restart. Yet that doesn't seem to be the case here...

Can someone explain what is going on?

Ege Ersoz
  • 6,461
  • 8
  • 34
  • 53

2 Answers2

0

You are missing,

WebConfigurationManager.Save();

in your post to edit.

The changes you are making are only being applied at run time. The reason you are not causing the app pool to restart is because you have not committed your changes.

Here is a reference I found: modify the web config at run-time

Do Note that in the long run as stated in the referenced link you should not store settings that are edited frequently in your web config. Use an XML or json file to store those settings and load them as needed.

Community
  • 1
  • 1
Nkosi
  • 235,767
  • 35
  • 427
  • 472
0

Unless you call the Save method on the configuration, It won't be persisted to the physical file(Web.config). That means, you will still be able to read the app setting entry values you set until the app pool recycles. But if your app pool recycle/IIS get restarted, you will loose whatever you set to the AppSettings.

Save method writes the config settings to the current XML configuration file.

Keep in mind that, the user or process that writes config file entries must have the following permissions:

  • Write permission on the configuration file and directory at the current configuration hierarchy level.
  • Read permissions on all the configuration files.

If you really want to persist the app settings entries to the files, you can do this

[HttpPost]
public ActionResult Edit(FormCollection collection)
{

    var config = WebConfigurationManager.OpenWebConfiguration("~");

    var db = config.AppSettings.Settings["DatabaseServerName"];
    if (db != null)
    {
       config.AppSettings.Settings["DatabaseServerName"].Value = id;
    }
    else
    {
       var dbEntry=new KeyValueConfigurationElement("DatabaseServerName",id);
       config.AppSettings.Settings.Add(dbEntry);
    }
    config.Save();
    // to do  : Redirect to a success action (PRG pattern)
}

enter image description here

In your case, to set the db server name & api keys, you should be calling the Save method so that they are persisted in the file and will be available later even after the app pool restarts.

Shyju
  • 214,206
  • 104
  • 411
  • 497