Assemblies, Web.config and App.Config -- Building failover logic - c#

How do I engineer failover logic properly if an Assembly (.dll) cannot find a web.config file?
Background: I've got our website code nicely modularized into two different .dlls. For simplicity's sake, let's call them:
website.dll
commonengine.dll
The website code and .aspx / .ascx files calls upon the commonengine library for all data layer stuff. For connection strings, the commonengine in turn looks not to the app.config but to the website's web.config file (that's my own preference -- I prefer to have our production constants all in one place). The website code occasionally (very rarely) needs to access stuff in that web.config file. All good so far (even though not entirely pure).
Here's the trouble. I've written a third module. It's a Windows Service (specifically, it's a POP3 checker/processor -- processing mailbox requests and using the commonengine.dll for some data layer stuff).
The problem is the Windows Service calls upon the commonengine.dll, and the commonengine.dll cannot find web.config anywhere because, after all, it's a Windows service (.exe) and doesn't live in a website directory.
What's the proper test/logic here to use app.config when a web.config file cannot be found? Can any ASP.NET configuration gurus give me some guidance here? Thanks much if so.

I never read Web.config explicitly, I use the System.Configuration class to read it (e.g. System.Configuration.ConfigurationStrings["conn name"]). It will automatically go to Web.config in an ASP.NET app and app.config in an EXE.
Of course, you still have to take into account the fact that the config section might be missing.

Related

Where does app.config belong?

i have a winforms app, the solution has two projects client (winforms) and the business logic(as Library classes). When i create a datset.xsd file in the client, it adds app.config file to the client. but why it adds it in the client?
App.config which contains the connection string should belong in the business logic (in the Library classes) because the business logic layer is the layer that accesses the database. To my understanding the the connection string part of the app.config should be encrypted. But why this app.config is placed in the client where the security risk is high, why typically developers do not place it in the business layer?
Configuration file App.config is for the entire application configuration not per library. Like Davin mentioned it's not a physical separation but rather logical where all libraries still get placed into the same folder when you compile an application and the main app.config file from the assembly that runs an application is used for getting configuration data for your application.
The file is not encrypted by default but it can be. Here is a thread that lists different ways of encrypting the web.config configuration data.
Encrypting appSettings in web.config
And here is a blog post about encrypting app.config file
http://weblogs.asp.net/jongalloway//encrypting-passwords-in-a-net-app-config-file

Dynamically Set Web.Config at Application Start for MVC

I have a web application built in ASP.NET MVC that will be used by several clients. Each client has its own database to store information, but each instance will have the same functionality. I am using tips from this question/answer How can I host multiple websites in IIS 7 and use the same MVC application for all them? to consolidate to a single app folder for easier maintenance.
Right now, I setup each client in its own folder and each with its own Web.Config file. There are a couple of appConfig settings as well as the connectionStrings that are unique to that client.
What I would like to do is have a single app folder that contains the MVC project, but the application then dynamically pulls the correct web.config folder (stored in another folder.) I will select the web.config probably based on the host settings (i.e. www.domain.com loads the domain.web.config file.)
I would like for this to update the behavior of the ConfigurationManagement object. I have seen several posts on how to load a configuration file (and most are regarding app.config for desktop apps) but not how to make it a semi-global change or unique characteristics of ASP.NET MVC and web.config.
How can I accomplish this?
What you are looking to do is called multi-tenancy. And this is quite complex task.
You can't really play about with web.config substitution and for one request give one file and for another request give another config. What if 2 requests from different tenants will come exactly at the same time?
At the moment we are converting our application to multi-tenancy and this is very complex task, so can't really be described in one answer on SO.
You can have a look on this write-up http://www.scribd.com/doc/140181293/setting-up-an-mvc4-multi-tenant-site-v1-1
Also if you google for "multi-tenancy MVC" you'll get many articles on that.
Basic principles for our multi-tenancy look like this: DI container is aware of different tenants and knows that request for tenant1.site.com should use configuration set 1 and for request tenant2.site.com configuration set 2 should be used.
Apart from DI container, no other component knows about tenants. And DI container orchestrates the configurations. Connection strings are sitting in configuration objects and these objects are given to EF contexts before they are created... somewhat complex.
If your case is simple and you don't use caches, to substitute the connection strings, I'd save them outwith web.config and provide them based on tenant request. Probably you can get away without complex DI setups.
The overhead of maintaining multiple config files is small if you use external config files to isolate the connection strings that are unique to the customer leaving the bulk of the config file unchanged.
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings configSource="connections.config"/>
</configuration>
For more options about resolving config information at runtime look at
http://msdn.microsoft.com/en-us/library/ms254494(v=vs.110).aspx
For app settings in an internal file see Moving Settings to another config file

Self-host ASP.NET application WITHOUT exposed files

I want to self-host an ASP.NET web application from a service that we have developed. Their are only 2 requirements, the first being no external applications to be redistributed, i.e. no solutions like xsp2 or IIS express, etc. Second, I'm trying to not leave aspx/code-behind files laying around on the filesystem. I'd prefer something that can host from embedded resources or from a compiled ASP.NET Web Application (.dll and placeholder aspx files).
I realize that anyone could decompile the binaries, etc, but I'm really just trying to not make it 100% easy to tinker with the web interface. I've looked at a few options, but none that will properly host a compiled Web Application WITHOUT an external application.
Are there any (preferably 100%-managed) libraries out there that can do this? Even if it's raw files in a virtual filesystem of some sort (although that would require a driver-installation which I want to avoid).
There is one Open Source Embedded C# Web Server on CodePlex but it is not actively developed.
You can however, fork it as per your needs.
http://webserver.codeplex.com/

How do I use log4net within a dll that does not depend on a client's app or web.config?

I want to be able to dynamically control the level of logging my Azure cloud-based applications perform. To do this I'm creating a shared log4net-based DLL.
There are lots of questions about log4net logging but almost all of them involve entering and manipulating settings in a config file or other text file. In the Azure cloud, changing the web.config means redeploying. I want to change the logging by making web service calls into the applications from an admin portal.
I also have several applications and I want each to use my new log4net-based DLL without having to store identical settings such as Appender details in each config file. The applications log the same, consistent data.
I do not want to use the Azure diagnostics because this will reduce performance of this large user base application. In addition, I want to reduce logging and diagnostics to a minimum (or disable completely) and only enable them at various levels to debug production problems or take snapshots of their performance. I don't want to redeploy my apps.
What's the best approach?
I would recommend not storing log4net configuration in web/app.config files but rather in a different file that can be updated externally (ie: in blob storage) and location of which can be dynamically changed from the Service Config or contents of which can be changed w/o redeploying.
Look into the log4net.Config.XmlConfigurator.Configure method. You can pass it many different parameters instead of just calling it with no parameters (no parameters default method reads from app.config files).
One way to do what you want is to pass that Configure method a public URL of a config file stored in your Azure storage. Location of the config file can be controlled from the Service Config.
Alternatively if you do not want to make the config file public, you can implement your own reader of the XML config from some private location in storage and pass the XML document to the Configure() method instead.
Check for more information here:
http://logging.apache.org/log4net/release/manual/configuration.html
I can think of 2 ways:
Use Web Deploy which just updates the files on the server without having to do the full blown deployment process.
Enable RDP on your Azure instances and just log in and alter the config file in situ, just like any other server

Control Caching in IIS7 from C#

I have situation described bellow:
In CMS was implemented two presentation server which aren't on same machine. Client want to enable IIS caching only on one machine, but changing manually web.config isn't suggested. So I am planning to make some C# code which will make changes in web.config in order to ensure proper cache settings. Is it possible or exist any other solution ( change other settings, edit other files...) for the problem?
"You can configure the element at the server level in the ApplicationHost.config file or at the site, application, or at the directory level in a Web.config file."
If you have physical access to the server you can run from the console appcmd.exe:
appcmd.exe set config -section:system.webServer/caching /+"profiles.[extension='asp',policy='CacheUntilChange',kernelCachePolicy='CacheUntilChange']" /commit:apphost
Check this link: http://www.iis.net/ConfigReference/system.webServer/caching
EDITED
The first answer to this question says how to configure caching at folder level, the 2nd answer for file level:
How to configure static content cache per folder and extension in IIS7?
If you didn't specify any caching rules at file or folder level, disabling global caching should do it.

Categories

Resources