How can I make a C# project's settings be user specific? - c#

I am writing a Web API 2.0 project and a test project using Visual Studio 2013.
In the test project, I saved some information in the Settings.settings file (under TestProject->Properties in the Solution Explorer). One of the things saved there is the connection string to a database that is stored locally.
Unfortunately, the connection string will be slightly different on each person's computer when they download the repo. When people push their code to the master repo it overwrites the connection string, affecting everyone else.
What is the best way to make this configurable for each user such that everyone can have their own database path, but pushing to master repo won't affect anyone?
Edit
I don't think this is exactly a duplicate of that other question. Although, yes, my configuration settings are stored in app.config (since they happen to be application settings rather than user settings), following the solution in the other answer will lead me with the same problem. The app.config will contain configSource="otherconfig.config", and when people push that file to the master repo, it will still clobber other people's values. I need something that allows the custom configurations to be source-controlled without affecting the other users of the project.

Visual Studio handles this automatically for WEB projects through Web.config transformations
You'll need to install a separate plugin for use with App.config and non-web projects. http://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859
The plugin basically adds the same functionality to app.config files, and works with the same syntax in the transform files.
Your best approach to this is to use Build Profiles. Have a developer-specific Web.developer.config and with that you get each user to choose their name in Configuration Manager. Then just make the new config, which is technically an XSLT make the changes needed for each team member.
Think of it as Debug vs Release configs, except in your case you'll have many Debug (one for each user). The Build profile you set doesn't get checked into TFS, so you're fine.
This is what a subconfig looks like:
<?xml version="1.0" encoding="utf-8"?>
<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="RavenDB" connectionString="Url=http://xxx/databases/xxx" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
</connectionStrings>
<appSettings>
<add key="BaseUrl" value="http://xxx" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>
<system.net>
<defaultProxy enabled="true" />
<mailSettings>
<smtp xdt:TrandeliveryMethod="Network" transform="Replace">
<network xdt:Transform="Replace" host="xxx" defaultCredentials="true" />
</smtp>
</mailSettings>
</system.net>
</configuration>
More info on web.config transforms
http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx

The way I handle this problem is by adding a folder into my app that has only assets that don't get included in the build/publish. One of the things I include in that folder is DeveloperName.App.config files for each of my developers. Then I leave the the actual App.config file out of source control. When they check out the project, they copy their personalized DeveloperName.App.config file to the project folder and rename it to App.config.
This isn't perfect, but it gives you at least most of the goals you're looking for: The developers each get their own App.config file they can maintain and keep in source control. And the changes they make to App.config don't clobber each other every check-in.

Related

How to Transform .Config on build for JetBrains Rider?

I'm trying to create custom configuration depending on the environment and it seems that the best way is to use config transforms. I'm trying to have the transform happen on build (to test locally), but the changes don't seem to work. Any ideas? Also what is the correct way to have "layered config" for environment on asp.net ?
have a go at this for me...
in the web.config (base)
add this configuration under the appSettings node
..
<appSettings>
<!-- Application Settings -->
<add key="IsTest" value="true" />
then in then right click the web.config and add a transformation (Add Config Transform) if you haven't already
and in that config you will only add the transform for that case in particular
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="IsTest" value="false" xdt:Transform="Replace" xdt:Locator="Match(key)" />
...
If you are debugging from visual studio your try to keep your "Debug" values in the root config, and then lets say if you add a UAT_Release configuration and a UAT_Release transformation then when publishing your application check that the transforms have applied to your web config (these should be merged back in the base config)
for none web.config transforms (app.config for example)
these do seem to get transformed based on the build configuration
the underlying issue with web configs is that the "original" can not be preserved because the bin for www uses the .config from the project directly. it is not staged as part of the build so applying the transform would perm change the the web config.
(there was an attempt extension to solve this for VS but not seeing one for rider just yet)
my solution was to
add a local build profile that was a copy of debug just with a diff name.
crate xdt transforms for all my "develop" settings
right click preview transform and manually apply this transform to web.config (its manual but best i got so far, the perform transform does seem to fail for web.config for me or would us that)
build project using same config as applied to web and all other configs seemed to auto transform for me.

How to define web.config local variables

I have a web application in C# with .NET Framework 4.0 and I'm trying to find a way to define a variable in Web.Config that can be referenced elsewhere within the Web.Config.
I want something like this.
<?xml version="1.0" encoding="utf-8"?>
<LocalWebConfigVars>
<add key="Var1" value="ServerName1"/>
<add key="Var2" value="DatabaseName1"/>
</LocalWebConfigVars>
<configuration>
<connectionStrings>
<add name="AppConnectionString" connectionString="DATA SOURCE=#Var2 ServerName=#Var1"/>
<add name="OtherStuff" value="#Var1"/>
etc...
Currently I have to keep 3 or 4 hard-coded values (some embedded others just the value) updated to the same thing and would like to make it easier to keep in sync.
Is this possible?
Thanks.
Edit:
Just some background. The reason this is becoming problematic is that we define the apps database instance (among other instance specific setting) in the web.config. We have multiple database instances in our test and production environments and if I need to switch to a different one them while testing something and miss one of the hand full of references I get some strange results. I'm trying to avoid this by defining it once and referencing it everywhere else.
Would not doing a simply .config transformation for each of your environments work, by setting up a project configuration & transform, you would be able to swap from environment to environment by the use of solutions configuration dropdown.
See this link
for more info on transforms on .config files

SlowCheetah - Getting it to work

I tried using the SlowCheetah extension, but I can't seem to get it to work. I think i may have missed a step somewhere.
I downloaded the extension and installed it.
The i created my web.config file and did the "add transform"
To test it, I was already using ELmah in my project, so I tried giving it different email address to send the error log for every config, and none in the web.config.
web.config
<elmah>
<security allowRemoteAccess="0"/>
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="C:\myLogPath"/>
<errorFilter>
<test>
<or>
<equal binding="HttpStatusCode" value="404" type="Int32"/>
<is-type binding="BaseException" type="System.FieldAccessException" />
</or>
</test>
</errorFilter>
</elmah>
web.debug.config
<elmah>
<errorMail from="error-debug#domain.tld" to="me#domain.tld" priority="High" xdt:Transform="Insert"/>
</elmah>
So, when i look at "preview transform", it seems like the result is what i want. Then I start my application (either with F5 or ctrl+F5) and purposely throw an exception on my website to trigger Elmah error reporting, but I never get any email. If I add the errorMail line in my web.config, I do get an email, so the problem is not coming from Elmah.
As I said, i feel like I may have missed a simple step in setting up the extension.
The problem you are running into isn't really with SlowCheetah, but how you are launching your web application from Visual Studio.
SlowCheetah will indeed add the necessary MSBuild Targets to your project in order to do transforms upon build, but only for things included in your project output (i.e. the \bin folder).
When you build a web application your web.config stays put, and only the assemblies are copied into your \bin folder. Visual studio fires up the WebDev server and points it to the root directory of your web application. Since your web.config hasn't been modified, it will always contain the original contents.
To my knowledge, slow-Cheetah supports config transforms for the app.config files but not web.configs on debug at present. It should put a transformed web.config file in the bin folder of your project but your project still reads from the config file in the root folder. Please have a look at a workaround at http://sedodream.com/CommentView,guid,68b7e248-b9f5-4d07-bdfe-eb037bcf2cbb.aspx. This works for me instead of using Slow-Cheetah.
You can also request for web config transform support for Slow-Cheetah on debug at
https://github.com/sayedihashimi/slow-cheetah/issues/39 They are considering adding web support on F5 to it.

NuGet behind a proxy

I figure out that NuGet allows proxy settings configuration since 1.4 version (June 2011). But, I can't find any command line example.
I'm trying to run some build and NuGet can't connect.
How do I configure the proxy settings on the command line?
Here's what I did to get this working with my corporate proxy that uses NTLM authentication. I downloaded NuGet.exe and then ran the following commands (which I found in the comments to this discussion on CodePlex):
nuget.exe config -set http_proxy=http://my.proxy.address:port
nuget.exe config -set http_proxy.user=mydomain\myUserName
nuget.exe config -set http_proxy.password=mySuperSecretPassword
This put the following in my NuGet.config located at %appdata%\NuGet (which maps to C:\Users\myUserName\AppData\Roaming on my Windows 7 machine):
<configuration>
<!-- stuff -->
<config>
<add key="http_proxy" value="http://my.proxy.address:port" />
<add key="http_proxy.user" value="mydomain\myUserName" />
<add key="http_proxy.password" value="base64encodedHopefullyEncryptedPassword" />
</config>
<!-- stuff -->
</configuration>
Incidentally, this also fixed my issue with NuGet only working the first time I hit the package source in Visual Studio.
Note that some people who have tried this approach have reported through the comments that they have been able to omit setting the http_proxy.password key from the command line, or delete it after-the-fact from the config file, and were still able to have NuGet function across the proxy.
If you find, however, that you must specify your password in the NuGet config file, remember that you have to update the stored password in the NuGet config from the command line when you change your network login, if your proxy credentials are also your network credentials.
Maybe you could try this to your devenv.exe.config
<system.net>
<defaultProxy useDefaultCredentials="true" enabled="true">
<proxy proxyaddress="http://proxyaddress" />
</defaultProxy>
<settings>
<servicePointManager expect100Continue="false" />
<ipv6 enabled="true"/>
</settings>
</system.net>
I found it from the NuGet Issue tracker
There are also other valuable comments about NuGet + network issues.
Just in case you are using the HTTPS version of NuGet, be aware that you have to set the values with HTTPS.
https_proxy
https_proxy.user
https_proxy.password
I could be wrong but I thought it used IE's proxy settings.
If it sees that you need to login it opens a dialog and asks you to do so (login that is).
Please see the description of this here -> http://docs.nuget.org/docs/release-notes/nuget-1.5
Another flavor for same "proxy for nuget": alternatively you can set your nuget proxing settings to connect through fiddler. Below cmd will save proxy settings in in default nuget config file for user at %APPDATA%\NuGet\NuGet.Config
nuget config -Set HTTP_PROXY=http://127.0.0.1:8888
Whenever you need nuget to reach out the internet, just open Fiddler, asumming you have fiddler listening on default port 8888.
This configuration is not sensitive to passwork changes because fiddler will resolve any authentication with up stream proxy for you.
To anyone using VS2015: I was encountering a "407 Proxy Authentication required" error, which broke my build. After a few hours investigating, it turns out MSBuild wasn't sending credentials when trying to download Nuget as part of the 'DownloadNuGet' target. The solution was to add the following XML to C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe.config inside the <configuration> element:
<system.net>
<defaultProxy useDefaultCredentials="true">
</defaultProxy>
</system.net>
The solution for me was to include
<configuration>
<config>
<add key="http_proxy" value="http://<IP>:<Port>" />
<add key="http_proxy.user" value="<user>" />
<add key="http_proxy.password" value="<password>" />
</config>
</configuration>
In the nuget.config file.
Maybe this helps someone else. For me the solution was to open NuGet settings on Visual Studio (2015/2017) and add a new feed URL: http://www.nuget.org/api/v2/.
I didn't have to change any proxy related settings.
On Windows Server 2016 Standard, which is what I develop on, I just had to open the Credential Manager Control Panel and clear out the cached proxy settings for Visual Studio which were no longer valid and then restart Visual Studio. The next time I opened the Nuget Package Manager I was prompted for proxy credentials, which got me working again.
See: https://support.microsoft.com/en-us/help/4026814/windows-accessing-credential-manager
Just a small addition...
If it works for you to only supply the http_proxy setting and not username and password I'd recommend putting the proxy settings in a project local nuget.config file and commit it to source control. That way all team members get the same settings.
Create an empty .\nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>
Then:
nuget config -Set http_proxy="http://myproxy.example.com:8080" -ConfigFile .\Nuget.Config
And finally commit your new project local Nuget.config file.
Hello for me going into
%appdata%/Roaming/Nuget/NuGet.Config and removing every line except for the package sources. Which should give something like this
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
Full path should be C:\Users<username>\AppData\Roaming\NuGet\NuGet.Config
Basically there was a proxy set, i don't how and why it was set but it was there and i couldn't ping it either.
Try this. Basically, connection could fail if your system doesn't trust nuget certificate.
Apart from the suggestions from #arcain I had to add the following Windows Azure Content Delivery Network url to our proxy server's the white-list:
.msecnd.net
Above Solution by #arcain Plus below steps solved me the issue
Modifying the "package sources" under Nuget package manger settings to check
the checkbox to use the nuget.org settings resolved my issue.
I did also changed to use that(nuget.org) as the first choice of package source
I did uncheck my company package sources to ensure the nuget was always picked
up from global sources.
As a late answer, for me nothing worked here. I guess this might depend on your company proxies or how the nuget is implemented but for some reason I had the following environment variables set: http_proxy and https_proxy. After I removed them, nuget started working correctly.
It's correlated, but not the same cenario here, but I would like to document for those on Linux.
I'm on Fedora 35 using VsCode and dotnet sdk 6 installed
To use dotnet add package behind proxy I have to use this format of command:
export http_proxy=http://[user]:[pass]#[server]:[port] && dotnet add package <package>

How to make the Setting works for Class Library project in C# 2.0?

I am putting the setting under the property of one of my C# Class Library project for app setting:
EUCAccountService_ConnectionString
EUCTelcoDB_ConnectionString
In the development, it works nicely. Until I deported to production, I realise that the component that use those thing .. it just hang. I found that under \BIN when it compiled dewaCorp.EUC.TelcoDB.Data.dll.config and open up that file and turn out nothing.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
How to make this works? I thought by compiling it, it turned to some sort config file or something. But it didn't.
I am appreciated your comment.
The properties are not stored in the .config file they are stored in the windows user profiles.
To store setting in the .config file add a config file to the executing assembly (take note is important to use the executing assembly) and store add the settings there for connection strings there is a special note for them.
<ConnectionStrings>
<ConnectionString />
</ConnectionStrings>
You'd better take a look at similar projects, such as log4net, and Enterprise Library.
http://logging.apache.org/log4net/index.html
http://www.codeplex.com/entlib

Categories

Resources