Does anyone know of a good way to store connnection strings centrally and share them accross several ASP.NET apps? It seams the web.config file is app-specific and I don't have access to the machine.config file in a shared hosting environment. I suppose
I could store them in a database, but I would still have to store the same connection string to connect to the database in multiple places!
I like how the .NET configuration framework works with inheritance (machin.config to web.config) but it would be nice for multiple applications to be able to share some portion of a config file (like the connectionstrings in my example), by specifying some
sort of intermediate file between machine.config and the application-level files.
The solution is to store the connection strings on the web.config of the parent web app. Note that the web site root is also an app, so you can store
a web.config in there (i.e. c:\inetpub\wwwroot\web.config) which will be inherited by all apps under it.
c:\inetpub\wwwroot\web.config -> common configuration.
c:\inetpub\wwwroot\app1\web.config -> configuration for app1
c:\inetpub\wwwroot\app2\web.config -> configuration for app2.
In the case the default web site root is off limits, you can create a root app to contain all other apps and store the common configuration there.
c:\inetpub\wwwroot\myrootapp\web.config -> common configuration.
c:\inetpub\wwwroot\myrootapp\app1\web.config -> configuration for app1
c:\inetpub\wwwroot\myrootapp\app2\web.config -> configuration for app2.
Jose Reyes
Microsoft Corporation
"This posting is provided "AS IS" with no warranties, and confers no rights."
Do the child apps still operate under there own application space, in other words, are their Application and Cache state bags still separate?
Also, how does the child's web.config know whether to "append" or "replace" a given configurationSectionElement. For instance, if I have a connectionString called "TestDB" in the parent web.config, can I add a connecitonString called "TestDB" in the child
which replaces the parent or can I only append to the existing collection? If elements can't be replaced, what about entire sections?
The merging of the configuration may vary for different sections. As a rule, the configuration closer to the page being requested will prevail over all the values set above on the configuration hierarchy. Settings can be locked on upper levels though.
For instance, if you have this section on the root app (c:\inetpub\wwwroot\web.config):
The value of 200 for the timeout will prevail for all pages on the myapp1 application.
With collections, the merging is little bit more complicated. The merging depends on the collection type and some collections may have overridden the way they are merged. For more information on this I suggest searching the Configuration API documentation.
In the particular case of the connection strings, if the section finds an item that already exist on the parents configuration, it will throw an exception (Parser Error Message: The entry 'TestDB' has already been added.) If you want to modify a connection
on the upper levels you can use:
Jose, I seem to be running into some trouble using the method you described. I have a VS 2005 solution with two websites in it. I would like to have these sites share connection strings. I have created a parent website (this is actually quite a pain since VS2005
deprecated the "Remove From Site" ability ) and placed the connection strings in its web.config file. However, now my solution won't compile. I get an error which states "It is an error to use a section registered as allowDefinition='MachineToApplication'
beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS." Both my child apps and the parent app are configured as Applications in IIS. I assume it has something to do with the fact that the web.config
file in the child apps have their own authentication sections. I thought I read somewhere that subdirectories that have web.config files of their own can't have certain sections (like the authentication section) in them. I'm not sure why this is, but if this
is what's causing my problem, then I obviously wouldn't be able to use the Parent app structure to share the connections string. Any thoughts?
There are two important pieces of information missing from you post above. One is the section name that generated the exception. The other is the path to the web.config where
that section is contained. Both pieces of data should be included in the exception (500) page. Can you please tell be what they are? Can you request the page outside VS?
Thanks, Jose.
Jose Reyes
Microsoft Corporation
"This posting is provided "AS IS" with no warranties, and confers no rights."
The section was the authentication section and the error pointed to the web.config file in one of the children.
Anyway, I tried removing all the apps from my solution and adding them back and it seems to be compiling now. I haven't had the time to see if the authentication is working on the child apps but will do so soon. In general does using a parent or root app
allow for child apps to either share the parent's authentication scheme or overwrite with there own? I would think this would be one way of setting up a Single-Sign On type of a system.
Would the following work?
I could set up Forms Authentication in the root app and deny access to two of the three child apps and allow it to the other. In this way, the two that are denied will require login according to the parent's authentication settings (in essence SSO). The
other app would not require login unless it had its own authentication configuration. I imagine this might work... one queston would be how the child apps access the IPrincipal User object created by FormAuthentication configuration of the parent App.
Yes, that's the idea of the merging configuration. You can setup a parent with configuration that applies to must of your apps, and override only where it differs. This is somehow similar to object oriented inheritance.
Note though that since they are different apps (or instances you may say), they share the same configuration (DNA you may say) but separate app domains. That is internal app data structure will be probably different (i.e. Cache, etc).
Jose Reyes
Microsoft Corporation
"This posting is provided "AS IS" with no warranties, and confers no rights."
I have been able to implement this "Parent app" framework with several configuration sections (including custom sections). I am having some difficulty with authentication, though. The Redirect FromLogin method doesn't seem to be working. from the child apps.
The page is postbahck, but is not redirected to the calling page (as specified in the returnUrl query parameter). The login form is located in the parent app and I have set the enableCrossAppRedirects attribute to true in the parent web.config file. Can you
point ot an online example of using theis sort of Parent/child architecture with forms authentication?
akashenk
Member
436 Points
218 Posts
Sharing connection strings across web apps
Jan 06, 2006 06:12 PM|LINK
Does anyone know of a good way to store connnection strings centrally and share them accross several ASP.NET apps? It seams the web.config file is app-specific and I don't have access to the machine.config file in a shared hosting environment. I suppose I could store them in a database, but I would still have to store the same connection string to connect to the database in multiple places!
I like how the .NET configuration framework works with inheritance (machin.config to web.config) but it would be nice for multiple applications to be able to share some portion of a config file (like the connectionstrings in my example), by specifying some sort of intermediate file between machine.config and the application-level files.
Thanks,
Al
josere
Member
497 Points
102 Posts
Microsoft
Re: Sharing connection strings across web apps
Jan 06, 2006 06:41 PM|LINK
The solution is to store the connection strings on the web.config of the parent web app. Note that the web site root is also an app, so you can store a web.config in there (i.e. c:\inetpub\wwwroot\web.config) which will be inherited by all apps under it.
c:\inetpub\wwwroot\web.config -> common configuration.
c:\inetpub\wwwroot\app1\web.config -> configuration for app1
c:\inetpub\wwwroot\app2\web.config -> configuration for app2.
In the case the default web site root is off limits, you can create a root app to contain all other apps and store the common configuration there.
c:\inetpub\wwwroot\myrootapp\web.config -> common configuration.
c:\inetpub\wwwroot\myrootapp\app1\web.config -> configuration for app1
c:\inetpub\wwwroot\myrootapp\app2\web.config -> configuration for app2.
Microsoft Corporation
"This posting is provided "AS IS" with no warranties, and confers no rights."
akashenk
Member
436 Points
218 Posts
Re: Sharing connection strings across web apps
Jan 06, 2006 07:30 PM|LINK
Thanks for the reply. A couple questions...
Do the child apps still operate under there own application space, in other words, are their Application and Cache state bags still separate?
Also, how does the child's web.config know whether to "append" or "replace" a given configurationSectionElement. For instance, if I have a connectionString called "TestDB" in the parent web.config, can I add a connecitonString called "TestDB" in the child which replaces the parent or can I only append to the existing collection? If elements can't be replaced, what about entire sections?
josere
Member
497 Points
102 Posts
Microsoft
Re: Sharing connection strings across web apps
Jan 06, 2006 09:19 PM|LINK
Yes, all apps run in ther own app domain.
The merging of the configuration may vary for different sections. As a rule, the configuration closer to the page being requested will prevail over all the values set above on the configuration hierarchy. Settings can be locked on upper levels though.
For instance, if you have this section on the root app (c:\inetpub\wwwroot\web.config):
<system.web>
<httpRuntime executionTimeout="100" />
</system.web>
and your app overrides this with (c:\inetpub\wwwroot\myapp1\web.config):
<system.web>
<httpRuntime executionTimeout="200" />
</system.web>
The value of 200 for the timeout will prevail for all pages on the myapp1 application.
With collections, the merging is little bit more complicated. The merging depends on the collection type and some collections may have overridden the way they are merged. For more information on this I suggest searching the Configuration API documentation.
In the particular case of the connection strings, if the section finds an item that already exist on the parents configuration, it will throw an exception (Parser Error Message: The entry 'TestDB' has already been added.) If you want to modify a connection on the upper levels you can use:
<connectionStrings>
<remove name="TestDB" />
<add name="TestDB" connectionString="new connection string here…"/>
</connectionStrings>
Microsoft Corporation
"This posting is provided "AS IS" with no warranties, and confers no rights."
akashenk
Member
436 Points
218 Posts
Re: Sharing connection strings across web apps
Jan 06, 2006 09:26 PM|LINK
akashenk
Member
436 Points
218 Posts
Re: Sharing connection strings across web apps
Jan 09, 2006 04:04 PM|LINK
josere
Member
497 Points
102 Posts
Microsoft
Re: Sharing connection strings across web apps
Jan 09, 2006 05:48 PM|LINK
There are two important pieces of information missing from you post above. One is the section name that generated the exception. The other is the path to the web.config where that section is contained. Both pieces of data should be included in the exception (500) page. Can you please tell be what they are? Can you request the page outside VS?
Thanks, Jose.
Microsoft Corporation
"This posting is provided "AS IS" with no warranties, and confers no rights."
akashenk
Member
436 Points
218 Posts
Re: Sharing connection strings across web apps
Jan 09, 2006 06:14 PM|LINK
The section was the authentication section and the error pointed to the web.config file in one of the children.
Anyway, I tried removing all the apps from my solution and adding them back and it seems to be compiling now. I haven't had the time to see if the authentication is working on the child apps but will do so soon. In general does using a parent or root app allow for child apps to either share the parent's authentication scheme or overwrite with there own? I would think this would be one way of setting up a Single-Sign On type of a system.
Would the following work?
I could set up Forms Authentication in the root app and deny access to two of the three child apps and allow it to the other. In this way, the two that are denied will require login according to the parent's authentication settings (in essence SSO). The other app would not require login unless it had its own authentication configuration. I imagine this might work... one queston would be how the child apps access the IPrincipal User object created by FormAuthentication configuration of the parent App.
josere
Member
497 Points
102 Posts
Microsoft
Re: Sharing connection strings across web apps
Jan 12, 2006 06:03 PM|LINK
Yes, that's the idea of the merging configuration. You can setup a parent with configuration that applies to must of your apps, and override only where it differs. This is somehow similar to object oriented inheritance.
Note though that since they are different apps (or instances you may say), they share the same configuration (DNA you may say) but separate app domains. That is internal app data structure will be probably different (i.e. Cache, etc).
Microsoft Corporation
"This posting is provided "AS IS" with no warranties, and confers no rights."
akashenk
Member
436 Points
218 Posts
Re: Sharing connection strings across web apps
Jan 16, 2006 01:16 AM|LINK