Измените свою первую строку на это:
var config = WebConfigurationManager.OpenWebConfiguration("~");
Как ни странно, OpenWebConfiguration ожидает виртуальный путь к файлу Web.config, исключая имя файла. Я предполагаю, что логика в том, что в любом каталоге будет только один Web.config, поэтому указывать имя не нужно.
Документация MSDN в конечном счете подсказывает нам здесь - если вы посмотрите на примеры, все они используют явные относительные пути, а при размещении в IIS позволяют вам указывать файлы конфигурации из других мест, например:
OpenWebConfiguration("/siteName", "Default Web Site", null, "myServer");
Добавление:
Так почему же OpenWebConfiguration("~/Web.config")
вообще работает? Я не уверен, что могу точно объяснить это, но попробуйте это для пинки: измените его на ("~ / Foo.bar") . Тот же результат! Вы можете прочитать - ваш же файл Web.config - но не можете написать! (теперь попробуйте добавить каталог foo.bar на ваш сайт, затем поместите в него файл Web.config ...)
Поскольку OpenWebConfiguration ожидает каталог (и, по-видимому, допускает несуществующие, если он находит Web.config в родительском), я думаю, что именно поэтому ошибочное указание ~ / Web.config в качестве «пути» позволяет нам загрузить корневой конфиг, но не сохранить его.