Refer a connectionstring from web config in another config file - azure

I am using NLog to write logs to my database,
I have created a file NLog.config which is writing logs to a text file as of now.
To write the logs to a database, I am following this tutorial.
However, the connectionstrings for diferrent environments can be only modified in Web.config. (I am using Azure App services). Is there any way I can refer the connection string from web.config in NLog.config.
TIA

If you not using ASP.NET Core (but "full" ASP.NET), you could use ${appsetting:name=..}
Install NLog.Extended with Nuget and use ${appsetting:name=..} in your config file.
e.g.
<target name="database"
type="Database"
connectionString="${appsetting:name=myConnectionString}" />
See also the ${appsetting} documentation
NB: It can only read <appSettings> and not <connectionStrings>

Related

what are all the locations in which connectionStrings can be defined for an iis site?

I'm trying to find all the locations in which a connectionString can be defined for an iis site (to write a script to extract them all).
I know it can be part of a web.config. I would like to have a complete list of files it can be configured in.
Does it make sense for it to be configured in the site code?
Which other configuration files can define a site's connectionStrings?
And a bonus question - how do I know the order of the files in which the connectionString is searched in ?
Thanks,
EDIT:
Additional info - all IIS sites are pure dotnet sites.
Also, specifying the general location of files, rather then file names, is also helpful.
E.g. - connectionStings can be located in external configuration files, whose location is defined at a in an appSettings element in the "%runtime install path%\config\machine.config" file.
Another option is to just link to the relevant docs.
My issue is that I haven't found anything conclusive.
As far as I know, there are several ways to configure connectionstring in ASP.NET applications.
Define it in code. This is the method used by many beginners. Because at this time they focus on code learning and logical understanding. But some people are accustomed to using it if the database is fixed, it does not need to be modified.
SqlConnection connection = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=mytest;Integrated Security=True");
Define it in web.config or App.config. The benefit of it is easy to modified connectionstring after publishing application. Developers can change web.config, no need to change code and deploy application again.
<connectionStrings>
<add name="mytest" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=mytest;Integrated Security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
Using External Configuration Files. ConnectionString is stored in a independent file for example connections.config. The benefit of it is modifying an external configuration file does not cause an application restart.
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings configSource="connections.config"/>
</configuration>
About list all connectionstrings, you can use ConnectionStringSettingsCollection. It can get a connection by name and provider name.
I found a pretty good source for the locations of the IIS dotnet Framework configuration files - https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc754617(v=ws.10)?redirectedfrom=MSDN#inheritance
You could define additional connectionStrings
In dotnet code.
In env.
In external config files.
For non-IIS scopes - such as user scopes and role scopes.
These 4 options are not specific to IIS.
I don't know where options (3) and (4) are defined, and I'm not sure if this list is complete. But by combing this list and the one in the doc, I think we have 99% coverage of defined connectionStrings.

.NET Core 2 Service Fabric console apps common configuration file

I'm trying to build out a bunch of stateful microservices written in .NET Core 2.1. These are not ASP.NET applications, no http interface, but rather designed as console apps that are consuming messages off a service bus.
I'm having a deuce of a time trying to figure out how to reference my appsettings.json file into the service packages. There's a bunch of articles related to using the appsettings.json file in an ASP.NET service fabric app (basically spelling it out in a webhost builder) but that's not applicable for me, since I'm not using ASP.NET.
I have a single appsettings.json file that all the microservices in this application should be able to use.
I also found this article Service Fabric include additional files which talks about putting it into an sfproj target for MSBuild, but there seems to be no information whatsoever about what the file structure looks like on the target end.
What I tried to do is add targets to my sfproj file like so:
<Target Name="AfterPackage" AfterTargets="Package">
<Copy SourceFiles="appsettings.json" DestinationFolder="$(PackageLocation)\appsettings.json" />
</Target>
and then in my service, I'd try to instantiate an IConfiguration object based upon ..\appsettings.json but as one might guess by now, the service, upon attempting to publish, throws a FileNotFoundException looking for the appsettings.json file, so clearly the file is in a different location relative to the micro service. (Of course, the publish failure just says there was a problem and rolls back, you have to dig into the the SF Explorer to actually see that message)
What should this configuration look like? I can't find any documentation describing what the file system of a stateful microservice looks like, I'm not clear on where I should be putting this common file, or how the services should be accessing the file. Some help would be appreciated.
I hope I got everything right.
Here are the steps:
Put appsettings.json into shared folder in *.sfproj and include it in project using Visual Studio.
Unload *.sfproj and start editing it as .xml
Add the bellow code right after the last <Target> element.
<Target Name="AfterPackage" AfterTargets="Package">
<Copy SourceFiles="appsettings.json"
DestinationFolder="$(PackageLocation)\%(_DeployableServiceProjectReference.ServiceManifestName)\%(_DeployableServiceProjectReference.CodePackageName)" />
</Target>
The _DeployableServiceProjectReference is the internal <ItemGroup> initialized by the previous targets.
These should force the package command to copy appsettings.json file to service's code package directory for each service references in *.sfproj.
Hope this helps.

How to override web.config values in custom section in Azure Web App?

It is possible in Azure Web App to override web.config AppSettings section easily. E.g. if I have the following web.config:
<appSettings>
<add key="AllowedCORSOrigin" value="http://localhost:26674"/>
</appSettings>
I can override it in the app settings UI in the portal like that:
I have also a custom section in the web.config:
<AdWordsApi>
<add key="OAuth2RefreshToken" value="TOKEN" />
</AdWordsApi>
Is it possible to override it somehow as well? I have tried AdWordsApi.OAuth2RefreshToken and AdWordsApi:OAuth2RefreshToken, but that does not work that easily.
P.S. It's interesting to know if it's possible with other custom sections like e.g if I want another authentication mode on the server.
<system.web>
<authentication mode="None" />
</system.web>
Short answer is that it is not possible.
The mechanism you describes only works with App Settings and Connection Strings. High level, the way it works is:
Your Azure App Settings become environment variables
At runtime, a special module sets those dynamically in the .NET config system. Note that the physical web.config is never modified.
But it would be hard to make such mechanism work on arbitrary config sections, as those could not be dynamically affected without modifying the physical file.
If you are using Visual Studio use web.config transformations to change configuration settings depending on whether you are running locally or deploying to Azure:
How to Transform Web.config
In simple terms you create one more more build configurations (typically Debug & Release). In your Visual Studio solution right-click on your existing web.config file and click "Add Config Transform", this will create a Web.Debug.Config and Web.Release.Config file which you can then customise with specific settings depending on the environment. Link this with your Azure build configuration and you can then have any combination of settings for local and remote deployment.
This is old but leaving this reference to how to use Azure Resource Manager to potentially solve this.
You can transform the values by the listed in VSTS by doing the following steps in App.Release.config:-
Add xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" in configuration section
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
</configuration>
Add xdt:Transform="Replace" in custom section like below
<AdWordsApi xdt:Transform="Replace">
<add key="OAuth2RefreshToken" value="TOKEN" />
</AdWordsApi>
Create variable token in the release pipeline e.g OAuth2RefreshToken
Then in file config use it as following
<AdWordsApi xdt:Transform="Replace">
<add key="OAuth2RefreshToken" value="#{OAuth2RefreshToken}#" />
</AdWordsApi>
If you are adding any in web.config --> Appsetting, you can overirde it in Azure App Service using variable prefix
Key Name: APPSETTING_AllowedCORSOrigin
Value: http://localhost:26674
https://learn.microsoft.com/en-us/azure/app-service/reference-app-settings?tabs=kudu%2Cdotnet#variable-prefixes

WCF Service Publishing and Fileless Activation : still create a .svc file

Using Visual Studio 2012, I have created a WCF 4.5 Service Library.
When the service is published to my local IIS, despite the serviceActivations section in the configuration file, a .svc file is still created.
I'm also using a custom factory in the configuration file, which, fortunately, isn't lost because serviceActivations overrides .svc files.
The configuration file look like this :
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true">
<serviceActivations>
<add factory="My.ServiceHostFactory" relativeAddress="~/BirtProxy.SoapReport.svc" service="BirtProxy.SoapReport" />
</serviceActivations>
</serviceHostingEnvironment>
The .svc file that is created is like this :
<%# ServiceHost Service="BirtProxy.SoapReport" %>
I have several other services where I don't have this behavior, but I can't figure out what's wrong. I don't want this additional file to be created.
Any Help appreciated.
The .svc file is created because the service isn't declared in the configuration node. As soon as I've added the service, the file creation is gone.

SharePoint and Log4Net

I'm looking for best practices to integrate log4net to SharePoint for web request, feature activation and all timer stuff.
I have several subprojects in my farm, and I would like to have only one Log4Net.config file.
[Edit]
Not only I need to configure log4net for the web application, which is easy to do (I use global.asax, and a log4net.config file, so I can modify log settings withtout reloading the webapp), but I also need to log asynchronous events:
Event Handler (like ItemAdded)
Timer Jobs
...
I implemented this recently and came up with a solution that worked for me.
Deploy your log4net config file to the 12 hive and the log4net dll into the GAC using a globally scoped solution. Then in your application code explicitly initialize log4net from the location of your global file. This allows you to log feature receiver, timer jobs and web application code.
[assembly: log4net.Config.XmlConfigurator(ConfigFile =
#"C:\Program Files\Common Files\Microsoft Shared\" +
#"Web Server Extensions\12\CONFIG\log4net.config", Watch = true)]
see here http://www.codeproject.com/KB/sharepoint/SharepointLog4Net.aspx
Firstly, you will need to modify the web.config where your SharePoint virtual directory resides. This is because you'll need to add SafeControl entries to trust the log4net assembly. You can update the web.config programmatically using the SPWebConfigModification class in a feature receiver. As you have to modify web.config anyway, you may want to consider including your log4net config inside and not set up an external log4net config.
However, if you'd still like to do this, it may work if you add the following to the web.config file:
<configuration ...>
...
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net configSource="log4Net.config">
...
</configuration>
The log4net.config file should then be able to live alongside your web.config. As Nat says, you could deploy this file as a solution package.
Assuming you are attempting to run a minimal trust, you will need to update your Code Access Security file to include the log4net assemblies as well. All of your custom SharePoint code should then automatically use your log4net configuration.
You could release the config file as part of the solution package(s) to the 12 hive (use STSDev) to create any packages). This would give you a set location for the config and any changes to it can be released in a controlled manner (i.e. no need for manual editm, just roll back and re-install the solution).
I developed a log4net feature and packaged it in a wsp file. The feature receiver adds an httpmodule to the the web.config and the httpmodule loads the log4net.config from the layouts direcory when the application start event is raised in the http module.

Resources