Why do my IIS site-specific application settings disappear? - c#

I'm hosting an ASP.NET C# website using IIS on Windows Server. I publish to the IIS server using Web Deploy. I have a few application settings that I configure via IIS' site-specific application settings - mostly passwords that I don't want in plain-text in my app.config within the project itself. Every time that I publish, the settings that I've created via IIS disappear. I think the publish is over writing them. I can't figure out how to get them to persist through publishes. Does anybody know how to get the IIS application settings to remain even through Web Deploy publishes?

Not sure if that solves your problem, but you could try something like this:
Every config section has an optional attribute named "configSource" to
point to an external file. Therefore you could break down your web.config
into several files and update them accoringly:
web.config:
...
<configuration>
<appSettings/>
<connectionStrings configSource="connectionStrings.config"/>
<system.web>
...
connectionStrings.config:
<connectionStrings>
<add name="defaultConnectionString" connectionString="..." providerName="System.Data.SqlClient" />
</connectionStrings>
Then you could set the connectionString.config to not be included in the output of the project and just keep it unchanged on the server.

You could also:
-create a new build configuration for deployment
-add a web.config transformation for this build configuration
-deploy using this build configuration
That's how I usually do it

Related

Why is web.config getting created on publish not on build the project in Asp.Net Core API?

I have Asp.net Core 3.1 API project. When I build it doesn't create any web.config file, but when I publish the API using VS 2019 in a folder, it creates a web.config file.
So why it's not creating web.config on build ( I think it should not create because there is no web.config file in the project) but why does it create web.config file on publishing?
Edit: I am trying to deploy the application through Octopus, So I copy the bin folder content, and I need the web.config also. So for time being, I have manually created the web.config in the project and then building the project. so it copies the web.config to the bin folder. So Is this the right approach? or is there any way to generate web.config in the bin folder without manually creating it?
As far as I know, the web.config is used to tell IIS about how to use asp.net core module and handler to host the asp.net core application. When you build and test the application in the VS, there is no need to create the web.config, since it will read the launchSettings.json not web.config.
Web.config is a server configuration file, it is used to configures the ASP.NET Core Module.
The web.config file may provide additional IIS configuration settings that control active IIS modules. For information on IIS modules that are capable of processing requests with ASP.NET Core apps, see the IIS modules topic.
Asp.net core web.config content(Without this file, we couldn't directly host the asp.net core application on IIS)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\basket.api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
</aspNetCore>
</system.webServer>
</location>
</configuration>
IIS requires a web.config file for apps that run there.
In ASP.NET Core, web.config is lazy-generated. The assumption (flawed, IMO) is that you don't need web.config until you are ready to publish to IIS. But what if you have your IIS app pointed to your local code instance so that you don't have to republish your app every time you make a code change and want to test it in IIS? Or what if, like OP, you want to use alternate deployment methods?
A workaround in that case is to publish your app once, take the generated web.config, and copy it to the root of your VS project (same level as the bin folder). Subsequent builds will then copy the web.config to bin\debug\net6.0. Still not ideal, but this is better than manually creating web.config and potentially introducing an error in the file.

Web.config in website root is interfering with additional application Web.config (IIS)

I have 2 separate ASP.NET web applications setup in IIS that need to interact as one.
I created a New Website in IIS. I put the files for App1 in the root directory of the Website. I then created a directory called Admin and added App2 files. I right clicked the Admin directory in IIS and clicked Convert to Web Application.
It seems like the web.config in the root (App1) is interfering with the web.config within App2.
Is there a better way to set this up? Should both be their own applications within an empty Website? I kind of wanted to avoid this since I want the effect of www.mydomain.com for the main app and then www.mydomain.com/Admin for App2.
Your Admin website will inherit settings from parent (and therefore the root website) web.config.
You can explicitly override settings in the Admin web.config.
Also for configuration sections that have collections, you can often use clear to clear settings from the parent, e.g.:
<connectionStrings>
<clear/>
<add ... />
</connectionStrings>
<appSettings>
<clear/>
<add ... />
</appSettings>

How to deploy ASP.NET application to production machine without having to change DB connection string manually

As it stands, right now when I deploy my web application I always go into my web.config file to change the server name etc from the connection string manually before deploying the application. Is there an easier way to deploy a web app without having to always change the server in the connection string?
Thanks
Use a transform Web.config When Deploying a Web Application Project:
How to: Transform Web.config When Deploying a Web Application Project
Web.config Transformation Syntax for Web Project Deployment Using Visual Studio
It depends on how you are deploying your web app, but one common way to do it is to use web.config transforms
http://msdn.microsoft.com/en-us/library/dd465326%28v=vs.110%29.aspx
we use WIX installer exactly for this purpose.
It can be customized, like in my case, to select DEV, QA or PROD env while installation.
Best thing is it uses underlying MSI installation framework, if thats the right word here.
Assuming you only need to change the connection string for just one specific Web Deploy then you can do that with a transformation as others have said. The following should show exactly what you need to do.
In Solution Explorer expand the Properties node to get the PublishProperties as in the following.
Right-click on the Web Deploy profile and select Add Config Transform as shown in the following.
You will get a Web.project - Web Deploy.config file in the Web Config node. The initial contents will be the following.
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
Change the sample to the following or add the following.
<connectionStrings>
<add name="csname"
connectionString="yourotherconnectionstring"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
Where csname is the name in the Web.config of your connection string that you need to replace in the deployment.
There are many other transformations possible but if you only need to change the connection string for a specific Web Deploy then that should be the most straight forward. It is saying that you want to search for the connection string that has the specified name and then change the connection string value during the deployment.

Hiding private details from open source projects

I have a .net github project that is basically a wrapper around a web API. In the test project, I am calling to the API using an API key. I need to keep this key private, how do I accomplish this in a visual studio project?
In some other projects, like python, I can have git ignore the file (config.py) and use something like config.example.py. But in visual studio's case, the project will not compile because of the missing file Config.cs. What is the proper way to solve this? I'm thinking of using this same method of ignoring the file and have them execute a build script that should rename Config.example.cs to Config.cs?
This is the perfect for .config files. Depending on whether its a web or console application, you will have a web.config or app.config file in your project.
You can use the appSettings section to store your API key.
To make things even easier, you can actually have this section read from another file, ie: specialappsettings.config and then just ignore that single file from your repository.
Modify your web.config (or app.config):
<configuration>
<appSettings file="specialappsettings.config">
</appSettings>
<system.web>
<!-- standard web settings go here -->
</system.web>
</configuration>
Create a new specialappsettings.config file:
<appSettings>
<add key="APIKey" value="YourApiKeyValue" />
<add key="AnotherKey" value="AnotherValue" />
</appSettings>
This can be accessed in your code via:
var apiKey = ConfigurationManager.AppSettings["APIKey"];
Notes:
You can keep your settings within the original web.config file as
well but this lets you ignore just the specific settings file from
your git repository without affecting the rest of the project's
necessary configuration details.
The same "key" can be saved in
either file however the external file will override the original
web.config file value.
You are probably looking for the App.config file for a project. It will be copied to <application>.exe.config when you compile it. Users can edit that config file as needed.
In that config file, you can add your API keys:
<configuration>
<appSettings>
<add key="APIKey" value="12345"/>
</appSettings>
</configuration>
Then you can access it from your code using ConfigurationManager.AppSettings:
string apiKey = ConfigurationManager.AppSettings["APIKey"];
One option is to use .config files instead of having secret keys hardcoded in sources.
More info Using Settings in C# and step-by-step guide
<configuration>
<appSettings>
<add key="SecretKey" value="0" />
</appSettings>
</configuration>
var secretKey = ConfigurationManager.AppSettings.Get("SecretKey");
Perhaps you can store the key outside of the Config.cs file and load it at run time.
Bonus, other people using your code won't have to recompile the project to change to their API key.

Web.config and different configurations in different projects missmatch

I'm using this code (in my DAL project):
ConfigurationManager.AppSettings["server"]
to access appsettings section in web.config file (from web project):
<appSettings>
<add key="server" value="server.name.com"/>
<add key="database" value="databasename"/>
</appSettings>
and in a Web.Debug.config I'm using a following transformation
<add key="server" value="MY-LAPTOP"
xdt:Locator="Match(key)" xdt:Transform="Replace"/>
after that when I start application the config file isn't transformed. First line of code returns the nontransformed infromation. What's wrong with the code? What am i missing?
I have tried to publish it and when I check config file everything is ok like it is ment to be.
The web.config transformation is only perform during the publish process. You can still enable it on every build, when you it F5, see
ASP.NET Web Projects: web.debug.config & web.release.config
SlowCheetah - XML Transforms
Making Visual Studio 2010 Web.config Transformations Apply on Every Build
It's an MSBuild task to add.

Categories