I'm having an issue where Visual Studio is modifying my web.config
for encoded values on publish, but not on build, which wouldn't be a major issue except it's incorrectly changing them.
Specifically, I need a tab character and it's changing 	
to a space, but I would really prefer it not change anything on a publish, especially if it didn't change it when running the app locally.
I am running VS 17.12.4 using .NET 4.8.09032.
I can recreate this by doing the below...
Create a new application - ASP.NET Web Application (.NET Framework) - select Web API, leave all other settings at default
Add the below to
appSettings
inweb.config
<add key="TabValue1" value="	"/> <add key="TabValue2" value="	"/> <add key="LTValue1" value="<"/> <add key="LTValue2" value="<"/>
Delete the
Values
controllerCreate a new controller and add this code:
[HttpGet] public HttpResponseMessage Get() => Request.CreateResponse(HttpStatusCode.OK, new { TabValue1 = ConfigurationManager.AppSettings["TabValue1"], TabValue2 = ConfigurationManager.AppSettings["TabValue2"], LTValue1 = ConfigurationManager.AppSettings["LTValue1"], LTValue2 = ConfigurationManager.AppSettings["LTValue2"] });
Create a new folder publish profile using Debug configuration
Publish the API
Run the API in localhost
Hitting the new endpoint on local host yields the below as expected, and the config file in the bin looks the same as the web.config.
{
"TabValue1": "\t",
"TabValue2": "\t",
"LTValue1": "<",
"LTValue2": "<"
}
However, the web.config
file in the publish directory looks like this:
<add key="TabValue1" value=" " />
<add key="TabValue2" value=" " />
<add key="LTValue1" value="<" />
<add key="LTValue2" value="<" />
I'm having an issue where Visual Studio is modifying my web.config
for encoded values on publish, but not on build, which wouldn't be a major issue except it's incorrectly changing them.
Specifically, I need a tab character and it's changing 	
to a space, but I would really prefer it not change anything on a publish, especially if it didn't change it when running the app locally.
I am running VS 17.12.4 using .NET 4.8.09032.
I can recreate this by doing the below...
Create a new application - ASP.NET Web Application (.NET Framework) - select Web API, leave all other settings at default
Add the below to
appSettings
inweb.config
<add key="TabValue1" value="	"/> <add key="TabValue2" value="	"/> <add key="LTValue1" value="<"/> <add key="LTValue2" value="<"/>
Delete the
Values
controllerCreate a new controller and add this code:
[HttpGet] public HttpResponseMessage Get() => Request.CreateResponse(HttpStatusCode.OK, new { TabValue1 = ConfigurationManager.AppSettings["TabValue1"], TabValue2 = ConfigurationManager.AppSettings["TabValue2"], LTValue1 = ConfigurationManager.AppSettings["LTValue1"], LTValue2 = ConfigurationManager.AppSettings["LTValue2"] });
Create a new folder publish profile using Debug configuration
Publish the API
Run the API in localhost
Hitting the new endpoint on local host yields the below as expected, and the config file in the bin looks the same as the web.config.
{
"TabValue1": "\t",
"TabValue2": "\t",
"LTValue1": "<",
"LTValue2": "<"
}
However, the web.config
file in the publish directory looks like this:
<add key="TabValue1" value=" " />
<add key="TabValue2" value=" " />
<add key="LTValue1" value="<" />
<add key="LTValue2" value="<" />
Share
edited Mar 3 at 21:44
marc_s
757k184 gold badges1.4k silver badges1.5k bronze badges
asked Mar 3 at 20:30
No NoNo No
112 bronze badges
1 Answer
Reset to default 0OPTION 1: Use CDATA Sections
You can use CDATA sections to prevent Visual Studio from interpreting the XML entities. This will ensure that the values are treated as literal strings.
<add key="TabValue1" value="<![CDATA[	]]>" />
<add key="TabValue2" value="<![CDATA[	]]>" />
<add key="LTValue1" value="<![CDATA[<]]>" />
<add key="LTValue2" value="<![CDATA[<]]>" />
However, note that when you read these values in your code, you may need to strip the CDATA tags if they are included in the output.
OPTION 1: Use Custom Configuration Sections
Instead of using appSettings
, you can define a custom configuration section that is less likely to be processed by Visual Studio during publish.
<configSections>
<section name="customAppSettings" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<customAppSettings>
<add key="TabValue1" value="	" />
<add key="TabValue2" value="	" />
<add key="LTValue1" value="<" />
<add key="LTValue2" value="<" />
</customAppSettings>
Then, in your code, you can read these values using:
var customAppSettings = (NameValueCollection)ConfigurationManager.GetSection("customAppSettings");
var tabValue1 = customAppSettings["TabValue1"];
UPDATE:
The option 1 solution is invalid xml for the config file and the project will not compile as it contains unescaped special characters within the value. the option 2 solution changes nothing about the behavior.
Unfortunately both options do not working as expected. So I can suggest one more option... Please review it.
OPTION 3: Use Base64 String
Step 1: Encode the Tab Character
Encode the tab character (\t) as a Base64 string. You can use an online tool or write a small program to do this. For example:
string tabCharacter = "\t";
string base64EncodedTab = Convert.ToBase64String(Encoding.UTF8.GetBytes(tabCharacter));
Console.WriteLine(base64EncodedTab); // Output: "Cg=="
Step 2: Update web.config
Replace the tab character in your web.config with the Base64-encoded value:
<add key="TabValue1" value="Cg==" />
Step 3: Decode the Value in Your Code
When reading the value from ConfigurationManager, decode the Base64 string back to the original tab character:
string tabValue1 = Encoding.UTF8.GetString(Convert.FromBase64String(ConfigurationManager.AppSettings["TabValue1"]));