ConfigurationManager.AppSettings getting null? - c#

I did not realize that: 'have a web.config in a separate class library and' was reading the web.config app setting from different web application.
I am using VS2010 target framework 3.5
I don't know what is wrong here but I am getting null when I try to get ConfigurationManager.AppSettings["StoreId"];
private string _storeid = GetStoreId;
public static string GetStoreId
{
get
{
return ConfigurationManager.AppSettings["StoreId"];
}
}
web.config:
<appSettings>
<add key="StoreId" value="123" />
</appSettings>

If you are UNIT TESTING you need A COPY of the APP.CONFIG inside the UNIT TEST PROJECT

Update
You can have an AfterTargets in your CsProj file that copies the config:
<Target Name="CopyAppConfig" AfterTargets="Build" DependsOnTargets="Build">
<CreateItem Include="$(OutputPath)$(AssemblyName).dll.config">
<Output TaskParameter="Include" ItemName="FilesToCopy"/>
</CreateItem>
<Copy SourceFiles="#(FilesToCopy)" DestinationFiles="$(OutputPath)testhost.dll.config" />
</Target>
Problem
The usual cause for this is due to context.
Cause
When you have a solution with two projects, if the App/Web.Config is in the main project it wont work if the context of the running application is the second project such as a library, unit test, etc.
Conundrum
To read values from the config in other projects (with System.Configuration) you'll need to move/copy the config file to the project with the running context. Unfortunately duplicating files defeats the tenants of good programming; OOP, Source Code Management, SOLID, etc.
Cool Solution
A nifty solution is adding config file shortcuts in other projects so you only update one file:
It would be nice to divide the contents of config files across project's. Elegantly, like Sharing Assembly Files as per answer #2: https://stackoverflow.com/a/15319582/495455 but alas it's by context

Disclaimer ;) This post is not to answer OP as it is too late but definitely it would help the readers who end up to this page.
Problem I faced : ConfigurationManager.AppSettings["uName"] returning null in my C# web api project.
Basic Things I checked for :
1) In code ConfigurationManager.AppSettings["uName"] , I was using exact key 'uName' as I had in web.config file,
i.e
<appSettings>
<add key="uName" value="myValue" />
</appSettings>
Checked that I haven't mis typed as userName instead of uName etc.
2) Since it is a Web API project it would have a file as web.config instead of app.config , and that too in root folder of your project. [refer the image].
Solution :
The solution that worked for me ,
Changed ConfigurationManager.AppSettings["uName"] to WebConfigurationManager.AppSettings["uName"]
and
made sure that I had
<appSettings>
<add key="uName" value="myValue" />
</appSettings>
in the right file ie.
Right file is not web.config in View folder
neither the debug or release web.config

and:
<appSettings>
<add key="StoreId" value="123" />
</appSettings>
is located in the web.config file of your ASP.NET application and not in some app.config file you've added to your class library project in Visual Studio, right? You can't be possibly getting null if this is the case. If you've added this to an app.config of you class library project in Visual Studio then getting null is perfectly normal behavior.

I just got answer DLL are called from another project not in the project where there are create.so entries in App.config should b move to calling project config file.
For example i have 2 project in my solution one class library and other console application.i have added class library reference in Console application.So if i add app.config file in class library project it through null exception.it works when i added app.config in console application.Hope it works

App settings are loaded into ConfigurationManager.AppSettings, but User settings (in Properties settings in your project properties) are not.

In Visual Studio, right-click on the config file, select Properties, and then change "Copy to Output Directory" to either "Copy always" or "Copy if newer".
Alternatively, manually add the following section as a child of the element in your .csproj file (this one is for "Copy always" for file "App.config"):
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

I tried all of these solutions but none worked for me. I was attempting to use a 'web.config' file. Everything was named correctly and the files were in the proper location, but it refused to work. I then decided to rename my 'web.config' file to 'app.config' and just like that, it worked.
So if you are having this issue with a 'web.config' file be sure to rename it to 'app.config'.

This happened to me when I was testing a Class Library (.dll). They were both in the same project but the App.config for the library had the settings I needed. The App I had written to test needed the settings because it was running the library.

I got this problem as I copied a project from the file explorer and renamed the project. This copied the Debug folder and as I didn't have it set to 'Copy if newer' it didn't overwrite the old App.config file.
Just delete the Debug folder and rebuild. Hope that helps someone.

I agree with above answer and I would like to add few more points
you should make sure you don't put space before and after the :
see code below:
private static string Client_ID = ConfigurationManager.AppSettings["ida:ClientId"];
if you put space between ida: ClientId it will not work and will return null
make sure your key value names are correct
you can try WebConfigurationManager

Happened to me just now, only when calling it from another project.
Apparently, at the other project, the reference has not been defined as a Service Reference but rather as a Connected Service. I deleted the reference and added it again.

string setting = ConfigurationManager.AppSettings["Setting"];
Make sure config file is in the same folder as code referencing it. Create a
helper class if it is not. Duplicating this could cause confusion should
someone forget it exists in two places.
Keep app settings in an app.config and not a web.config for AppSettings.I had this issue with a key in the web.config.

Related

Prevent Config File From Publishing With Click-Once Deployment

I'm trying to use Click-Once publishing, trouble is, it's publishing also the Config file, which has the connection strings that I use on my development computer, not the correct ones I use in the production environment. How can I prevent the Config file from being published more than the first time? I tried in properties to not include it in the publishing list, but there is no option to do that.
Config files are part of Deployment since they store all the necessary settings which are used inside Addin.
If I understand the problem correctly then, you want to use some setting, say HOSTURL=http://example.com when Addin is in production environment and HOSTURL=http://localhost when you are developing the Addin and you are expecting all this to automatically without human involvement.
Then, you may try one of these:
[1] Try find the ClickOnceLocation and use settings depending upon value the ClickOnceLocation.
Assuming ClickOnceLocation contains "Debug" while you are developing/debugging the Addin.
//CodeBase is the location of the ClickOnce deployment files
Uri uriCodeBase = new Uri(assemblyInfo.CodeBase);
string ClickOnceLocation = Path.GetDirectoryName(uriCodeBase.LocalPath.ToString());
if(ClickOnceLocation.Contains("Debug"))
{
URL = "http://localhost";
}
else
{
URL = //from app.config
}
[2] Updating the app.config by using build configurations
There are some tricks you could use so that a different file with the values to the production server get picked up during publish.
You can have two separate config files one for local deployment/debugging and one for a real published or production version of the application. The debugging config file could point to the localhost server whereas the real published config file could point to the real server. You can then configure the build configurations such that the appropriate config file is picked up depending on the Active build configuration.
To add two different app.config files to the project, you can update the reference to app.config in your project file. The app.config is defined in the project file (vbproj or csproj) with the following xml:
<ItemGroup>
…
<None Include=”app.config” />
</ItemGroup>
There may be other nodes in the ItemGroup along with the app.config node. Delete the just app.config from this ItemGroup node and create a new ItemGroup under the node with the following xml:
<ItemGroup Condition=” ‘$(Configuration)|$(Platform)’ == ‘Debug|AnyCPU’ “>
<None Include=”app.config” />
</ItemGroup>
<ItemGroup Condition=” ‘$(Configuration)|$(Platform)’ == ‘Release|AnyCPU’ “>
<None Include=”publishedapp.config” />
</ItemGroup>
This basically means that the regular app.config file will be used when the Active configuration is set to Debug and the modified app.config with the real production variables stored in the “published” subfolder of the project is used when the active configuration is set to “Release”.
You can change the ItemGroup conditions to match other build configurations that you may have defined. One possibility is to have a separate “Publish” configuration defined based on the “Release” configuration but only used when you are actually going to publish an application.
An additional disclaimer with this process is that the VS project system itself and the designers are not aware of the additional app.config file; Visual Studio is only aware of the original file. The modified app.config with values for a production environment is only used by the msbuild process. So if you update the main app.config through the Settings Designer, the modified app.config will not be updated and you have to manually update the file.
Once you have configured your project appropriately you can simply switch between the different build configurations to change the config file and publish the application from Visual Studio without having to go through the update and re-sign process.

swagger-ui returns 500 after deployment

Out of the box configuration works perfectly on my machine, no problems at all.
But when I deploy to our test environment - I get the following message
500 : { "Message": "An error has occurred." } /api/swagger/docs/v1
The deployment is to default web site/api
Im guessing it has something to do with the baseUrl or something like that,
but I have no idea of even where to begin.
My routes work fine within the project - I can call all my webapi endpoints and they respond correctly.
any help would be much appreciated
When debugging I was using the debug config (Which I had generated XmlComments for: Properties -> build tab -> Output -> XML Documentation File)
I had not done this for my release configuration (duh...) - now everything works
thank you #VisualBean.
As it was not so obvious for me .... how to... a simple image.
In Project > Your Project properties > Build Tab
Swashbuckle is hiding the real error message due to your customErrors setting in web.config. If you set customErrors to off you should get a better error message.
<system.web>
<customErrors mode="Off"/>
</system.web>
As stated in the accepted answer you have to make sure the XML documentation file output is in bin and not bin\Debug or bin\Release (verify this for all build configurations).
I still got the 500 response because I use multiple XML documentation files.
In my SwaggerConfig implementation I include XML documentation files from two projects (the WebApi project itself and a class library that is referenced by the WebApi project):
c.IncludeXmlComments(string.Format(#"{0}\bin\MyWebApiProject.xml", System.AppDomain.CurrentDomain.BaseDirectory));
c.IncludeXmlComments(string.Format(#"{0}\bin\ReferencedProject.xml", System.AppDomain.CurrentDomain.BaseDirectory));
The XML documentation file of the WebApi project was published correctly to the bin folder of the site, however the XML documentation file of the referenced project was not (even though it appears in the bin folder of the compiled project).
So you need to modify the WebApi project file (.csproj) in a text editor and add the following sections at the bottom (replace ReferencedProject):
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForMsdeployDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\ReferencedProject\bin\ReferencedProject.xml" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
See How do you include additional files using VS2010 web deployment packages? for a full explanation.
The issue is that running dotnet publish with -r Release does not produce XML file. However, dotnet publish with -r Debug does in fact produce the file. This explains why people are only getting this issue when they are deploying to environments OTHER than locally, then kicking themselves when the find the exception only occurs on prod.(ITS THE RELEASE) In order to reporoduce, simply run those command locally and view output directory and you should see the issue.
(UPDATE) The fix for me was to actually go into .csproj file and add a line to ensure that the file was copied over always.
Diff shown below
The accepted answer should be the first thing you try.
However, I have my XML output set to go to App_Data\ and have my Swashbuckle configured to read from that directory, so, it doesn't matter which way it gets built: the xml files are going to 'be there'. Nevertheless, I was still getting the error...
I found over at MSDN's forums #enough2012's answer:
select "Remove additional files at destination" in the "File Publish Options" within the "Settings" pane of the Publish dialog.
Worked like a charm!

web.config, app.config priority / dependancies and usage on compilation

Just a quick question. I have a solution splitted in multiple projects. In one project, I have the database interactions and my EDMX. In this project, I have my app.config file with some connections strings.
This project, is imported as dependancy in a Web project. In this one, I have my Web.config where are defined (or "overriden") connections strings.
I'd like to know what are the mechanisms used to configure the database connection. From what I understood, the Web.config has all priority over App.config. But what I'm wondering is, is the App.config in dependancies projects used at compilation time ?
For instance :
Project A => app.config :
<connectionStrings>
<add name="A" connectionString="myConnectionStringA"/>
<add name="B" connectionString="myConnectionStringB"/>
</connectionStrings>
And the same in Web.config but with :
<connectionStrings>
<add name="A" connectionString="myConnectionStringC"/>
<add name="B" connectionString="myConnectionStringD"/>
</connectionStrings>
Which one will be used to define the connection to the EDMX ? In one hand, at compile time, logically it would be A & B used to define it, and C & D would be used at runtime.
But i'm not sure about it and for me, once the dll is "configured", I don't see how can C and D be used instead of A & B.
Could someone explain it to me please ?
Thanks !
The config file that is used at runtime is the one related to where you are launching your application. If you launch the projectA it will be the App.config file.
Actually it will be the file generated by the compilation on the proper directory "Debug" or "Release"
When you run your web project it will be the Web.config file there.
The dll isn't "configured" with the values from the config file, they are read when the application starts running and this will depend on the application that is running.
That is why if you change the values they will change when you relaunch the application without any need to recompile the project.
When designing your entities in Visual Studio, the connection string that is stored in the app.config file of the project is used.
Even though you add a reference to the project from the web project, the app.config of the referenced project is not used at all in the context of the web project. Of course, it can be used as a blueprint when adding the connection strings to the web.config.
The config file that is relevant to the web project is the web.config. So when running or publishing the web project, the settings that are used are the ones in the web.config.
They do not override the settings of the app.config in the sense of a fallback like "if the connection string is not configured in the web.config file, then I use the ones stored in app.config".
It is required that you add the connection strings that you want to use when running the web project to the web.config file, otherwise you'd encounter an error if you used the Entity classes.
For details on configuring ASP.NET web applications, see this link.
But i'm not sure about it and for me, once the dll is "configured", I
don't see how can C and D be used instead of A & B.
The config values are fetched when the progam is running, not when it is compiled.

How to read values from App.config in .Net 4.0 using configurationManager?

I am creating a windows service in .Net 4.0 and testing some functions of said service with a windows forms client by referencing the service project.
The service project has an App.config file and that file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<clear />
<add name="myLocalMySQLDBUsername" connectionString="username"/>
</connectionStrings>
</configuration>
When a function belonging to the service calls:
ConfigurationManager.ConnectionStrings("myLocalMySQLDBUsername").ConnectionString
a null reference error is thrown because my connection string is not loaded. The only connectionStrings that are loaded are from the machine.config file located in c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Config\machine.config
If I create an application scope setting for the service, I can get that setting by using the My.Settings.setting -> so it's not like the App.config file is not being read.
My question is: why are my connectionStrings not being loaded from the App.config file?
Thank you for your help.
UPDATE:
Also, at this point, even a work around would be appreciated; the only reason for using app.config is to be able to encrypt the contents using the DpapiProtectedConfigurationProvider (the contents will have some username/password values for service and database connections).
I tried creating an AppSettings section manually in the app.config but those settings were also not read by the configurationManager (count = 0).
UPDATE 2:
Per a suggestion, I tried to manually open the app.config file like so:
Dim exePath As String = System.IO.Path.Combine(Environment.CurrentDirectory, "ServiceName.exe")
Dim myConfig As Configuration = ConfigurationManager.OpenExeConfiguration(exePath)
So here is the weird part, when I look inside, path is correct (points to my app.config) but the connectionStrings are still being loaded from the machine.config file (my connectionStrings are not loaded)!! ARGH
UPDATE 3:
Okay, so, I figured it out. When referencing a project(parent) from another project(child), the child's app.config is used even if the parent's classes are being used. Thus, I can get the connectionStrings to show up if I copy them over to the child's app.config. When trying to open it manually, my currentDirectory was of the child, not the parent (strange how it did not throw an exception - it wouldn't have been able to find the config file ... it just silently used the machine.config ... oh well).
Thanks all for the help!
The first thing you'll want to do is make sure that the service account has access to the file (if not running as SYSTEM). It sounds like it should be ok though since you mention My.Settings.Setting works.
The other thing to look out for is to make sure that the app.config has the name of the service executable in it - so if the service exe is MyService.exe the app.config must be named MyService.exe.config.
The last thing to make note of: libraries will read from the executable's app.config that loads the library, not the app.config that is with the library. So if you have a project for the service executable MyService and a project for the library MyServiceLibrary the code in the library will read the app.config from MyService not MyServiceLibrary.
I saw some people say this problem might be fixed by manually re-adding a reference to System.Configuration.dll
SIDE NOTE: If that really is you whole app.config file and not just a snippet then that is your problem... you're app.config file should be MUCH more complicated or .NET will not be able to load it.
WORK AROUND: Use the configuration manager to open this config file (there is an API for that.) You can't get it to load auto-magically just tell the config manager to open it.
I still think the problem is your config file is invalid -- could you please post the FULL file?
Make sure the config file is deployed to the same folder as the executable file, and that it's called your.assembly.exe.config.
I had a similar problem, but in my case it was because I had changed the project's namespace. This is also used as the application settings section element name in the config file, so the code was not finding the new section name. Fiddling with one of the custom setting's values in the project properties and rebuilding caused the new section to written into the app.config alongside the old ones which was what indicated the issue to me.

Multiple .NET Configuration Files and Setup Project Problem

In order to handle settings for different deployment targets, I moved application settings from app.config to its own file and included that file in app.config via configSource. I also created a settings file for each target.Here is an illustration:
Project A
app.config (references settings.config)
settings.config
settings.Release.config
settings.Debug.config
During post-build, I copy the appropriate settings.{configuration}.config to the output directory. This is working fine so far and I can see settings.config file in the project output directory containing settings for the current build configuration: Release, Debug, etc.
However, I am having a problem with the setup project that I have for this project (Project A). Initially, it was not including settings.config file. So I set the build action for settings.config file as Content and I added content files from Project A to the setup project. This ensured that settings.config file was included in the setup. However, since the setup project appears to be picking settings.config file from the project directory instead of the output directory, settings.config file included in the setup is not what it should be. I want the one from the output directory to be included in the setup program since that one is the correct one for the current build configuration. I tried the following:
Added settings.config as a file to the setup project. However, it seems like I can only specify absolute path. So when I add it from the output directory of a particular build configuration (..bin\debug\settings.config), it does not work in other build configuration since (..bin\debug\settings.config) does exist in the directory specified. I looked into using relative paths or dynamic paths in the setup project where the build configuration could be specifed as part of the path but I could not find anything.
I considered using pre-build event to actually modify settings.config file in the project directory and then have it copied over the output directory by setting its 'Copy to Output Directory' to copy always or copy if newer. This should ensure that the appropriate settings.config is copied to the output directory just like the post-build based solution and should also ensure that the contents of settings.config file is updated before the setup project includes it. However, I don't like this solution because I would have to make sure settings.config file is writeable before I can make any changes since it is source controlled. If it is readonly, then I need to flip it to writeable, make changes, and then set it to readonly again. It is adding extra complexity.
I was wondering if anyone has a better idea or knows a setup project trick that allows me to include settings.config file appropriate for the current build configuration in the setup program.
Thanks
If I had to approach this problem, I'd start by asking the following question:
Why does settings.config have to be under source code control if settings.Debug.config or settings.Release.config provide the same information?
The answer, if I read your question correctly, is because you needed to force a settings.config file to appear as part of the build output. I'm guessing this is because your setup project is using the built in "Primary output" choice.
What you can do instead is add that file to your setup project as an explicit file reference. Right-click on the setup project and choose add / file, then select the file you want to include. As you'll notice (unless it's been fixed in VS2008 which sadly I'm not yet allowed to use at work), there is a very annoying limitation placed on manually added files - there is no way to make the path build configuration aware. You can work around that by copying the appropriate settings.config file to a common location (e.g. bin/Configuration) and picking it up from there. This does limit you to building Debug and Release versions sequentially, rather than in parallel, but for many this probably isn't a huge problem.
If you aren't required to use VS setup projects, I strongly encourage you to take a look at WiX (Windows Installer XML - see http://wix.sourceforge.net/ for more information). That will easily allow you to accomplish what is necessary, although if you are unfamiliar with the internal workings of Microsoft Installer the initial learning curve could be a little steep. Microsoft use WiX themselves for some pretty significant setup tasks (e.g. Office 2007, SQL Server, etc.). It had been hoped that WiX would become part of Visual Studio (for VS 2010), but sadly that is no longer the case.
I decided to go about achieving the same result (being able to have different configuration settings for different target environments) in a different way. So here is how I implemented it and it is working great. I read some of the posts here at SO about XmlMassUpdate task from MSBuild Community Tasks and decided to utilize it. Here is what I did:
1) For each project that needs to have different settings depending on the target environment, I added an xml file called app.config.substitutions.xml or web.config.substitutions.xml to the project. So, the project looked like
Project A
app.config
app.config.substitutions.xml
app.config.substitutions.xml file has the settings substitutions that XmlMassUpdate will process and apply to app.config file. Below is a sample substitution file that I use:
<configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
<substitutions>
<Development>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="DevValue" />
</appSettings>
</Development>
<Test>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="TestValue" />
</appSettings>
</Test>
<Release>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="ReleaseValue" />
</appSettings>
</Release>
</substitutions>
</configuration>
For details on how to specify substitutions, take a look at the documentation for XmlMassUpdate or just do a search on it.
2) Now I need to run XmlMassUpdate as part of build automation (TeamBuild/MSBuild). So in BeforeCompile in TeamBuild build definition file (basically a proj file), I added the following to run XmlMassUpdate on config files that have a corresponding .substitution.xml file
<PropertyGroup>
<SubstitutionFileExtension>.substitutions.xml</SubstitutionFileExtension>
<TargetEnvironment>Test</TargetEnvironment>
</PropertyGroup>
<Target Name="BeforeCompile" Condition="'$(IsDesktopBuild)'!='true'">
<CreateItem Include="$(SolutionRoot)\**\app.config;$(SolutionRoot)\**\web.config">
<Output ItemName="ConfigurationFiles" TaskParameter="Include"/>
</CreateItem>
<CreateItem Include="#(ConfigurationFiles)" Condition="Exists('%(FullPath)$(SubstitutionFileExtension)')">
<Output ItemName="ConfigFilesWithSubstitutions" TaskParameter="Include"/>
</CreateItem>
<Message Text="Updating configuration files with deployment target specific settings..."/>
<XmlMassUpdate
ContentFile="%(ConfigFilesWithSubstitutions.FullPath)"
SubstitutionsFile="%(ConfigFilesWithSubstitutions.FullPath)$(SubstitutionFileExtension)"
ContentRoot="/configuration"
SubstitutionsRoot="/configuration/substitutions/$(TargetEnvironment)"/>
</Target>
Note that config files are read-only during the build, I make sure to set them writeable before running this task. I actually have another custom MSBuild task that runs before XmlMassUpdate that handles common settings throughout all of the config files such as connection strings. That task makes the config files writeable. I also don't check modified config files back to the source control. They're (appropriate config file for the deployment target) included in the installer.

Categories