using connectionstring from web.config instead of app.config - asp.net

I have a class library project in which I've added a dataset which talks with sql server. The output of this project is to be consumed from a web application project. So I intend to put my connection string in the web application project.
Did a couple of things. In order to make my adapter use a different connection string, I had come across this. But I finally found doing the following convenient:
Dim adapter as New MyReqeustTableAdapter()
adapter.Connection.ConnectionString = sMyConnectionString
Then I tried taking the connection string from my configuration (app.config) to kind of simulate . I added a section manually with key "myconstr". My ideas was to do something like:
sMyConnectionString = ConfigurationManager.ConnectionString("myconstr").ConnectionString
But my intellisense couldn't not detect ConfigurationManager. So had to add the appropriate reference to the project.
Next I added a connection string via the settings designer for the web application project. I gave the above key for referencing it. However the above statment seems to throw a null reference exception.

Suppose you have created a class library. In it you've defined a Settings property which goes like:
Properties.Settings.Default.ProjectName
Visual Studio might auto generate some configuration for you as follows:
(app.config)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="MyDllProject.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<MyDllProject.Properties.Settings>
<setting name="ProjectName" serializeAs="String">
<value>MyDllproject</value>
</setting>
</MyDllProject.Properties.Settings>
</applicationSettings>
</configuration>
Now say you add this assembly to an project. And you access its settings, you'd most probably get MyDllproject as it value. This is in spite of adding any configuration. Why? Because when the assembly was generated it was kind of written into it. And the code written is such that in the absence of a configuration override use what was defined in the app.config at the time of generation.
Now in your target project, you simply add the necessary sections in the configuration file in the following pattern
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<!-- start: copied from app.config of class library -->
<section name="MyDllProject.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"
/>
<!-- end: copied from app.config of class library -->
<!-- other sections may follow -->
</sectionGroup>
</configSections>
<applicationSettings>
<!-- remember to maintain the same order as how it was defined in the sectionGroup -->
<!-- start: copied from app.config of class librarly -->
<MyDllProject.Properties.Settings>
<setting name="ProjectName" serializeAs="String">
<value>ConsoleProjectB</value>
</setting>
</MyDllProject.Properties.Settings>
<!-- end: copied from app.config of class library -->
<!-- other configurations settings may follow -->
</applicationSettings>
</configuration>
Thats it.
Here is a small project sample I've linked to for the same: http://sdrv.ms/16ksPef

you can add reference to System.Web and use System.Web.Configuration.WebConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString) from the class library project

A configuration file (app.config) which is defined in a class library project cannot be - automatically - consumed by the system. The only config file that can be consumed is the web.config file in web applications or *myexe.exe*.config in exe applications where exe file is *myexe.exe*.
So you seem to be trying to add app.config to the class library. That ain't gonna work.
It is possible to link a second config file to the web.config but that probbaly is no help to you.

Basically, what you need is a possibility to change a global parameter of your library from outside. Using app.config by itself does not give you that possibility straight away -- you have not exposed your library internal settings yet. With that in mind, one very straightforward way to achieve exposure is to create in your library an assigner for the app.config.
public static class Setter
{
public static void Set(string name, string value)
{
Properties.Settings.Default[name] = value;
}
}
Then, at web application start in global.asax, or elsewhere:
MyLibrary.Setter.Set("X", ConfigurationManager.ConnectionStrings["Y"].ConnectionString);

From your question I think you're building an n-layered application. I think you're better off the two options you mentioned.
You should just create a base class for your DAL (Data Access Layer) classes that will have a public property that contains that the connection string.
btw it will help you hide/secure your connection string instead of storing it in a file that could be easily read by anyone who have or gained access to your host
public class DALBase
{
public static string connString
{
get { return "Data Source=localhost\\SqlExpress;Initial Catalog=theDb Integrated Security=True"; }
}
}

Related

How to use ASP.NET 4.8 ConfigBuilders with system.serviceModel section of web.config

I have an ASP.NET 4.8 app that I am trying to integrate configuration builders into. I have installed the NuGet package Microsoft.Configuration.ConfigurationBuilders.Environment and added the required sections to Web.config (heavily truncated here).
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false"/>
</configSections>
<configBuilders>
<builders>
<add name="EnvironmentExpand" mode="Expand" type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Environment" />
</builders>
</configBuilders>
<system.serviceModel configBuilders="EnvironmentExpand">
....
</system.serviceModel>
</configuration>
When I run the application I get an HTTP 500 response from every action, with the message Unrecognized attribute 'configBuilders'. Intellisense in Visual Studio also highlights configBuilders and says The configBuilders attribute is not allowed.
If I remove the configBuilders attribute from system.serviceModel the application runs correctly although of course none of the placeholders in that section are expanded.
If I remove the configBuilders attribute from system.serviceModel and add it to another section, for instance connectionStrings, the application runs and the placeholders in the connectionStrings section are replaced.
Clearly there's something different about the system.serviceModel section but I don't understand what or how I can work around it so that I can replace placeholders in there.
If you look at your machine.config, you'll see that system.serviceModel is a sectionGroup and not a section. ConfigurationBuilders only apply at the section level. WCF and ASP.Net for better or worse have their large configuration divided into multiple sections.

Avoid inherited ELMAH errors in an ASP.NET subapplication

I have a parent IIS application that uses ELMAH and a child ASP.NET application (virtual directory) that doesn't use ELMAH. When I try to browse my subapplication I get this error:
Could not load file or assembly 'Elmah' or one of its dependencies. The system cannot find the file specified.
Which is understandable as my child application's bin folder doesn't contain any ELMAH assemblies.
The problem probably is that the parent web.config file contains this:
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>
</configSections>
As far as I understand there is no way to stop <configSections> inheritance, see e.g. How to stop inheritance of <configSections>in Web.Config. Is there a way to run my ELMAH-free subapplication then?
You cannot keep your subapplication ELMAH-free because of the parent configuration. However - since I imagine you don't want to reference the assemblies from the parent - what you can do is tell your subapplication to look for assemblies in the parent bin folder with the probing configuration.
This way your subapplication doesn't need to know what assemblies exist for the parent, only that if an unknown assembly is needed it can be found in the parent folders
Edit: That's indeed a bummer. Clearing and removing configsections tags was considered too complex by Microsoft :
<clear /> and <remove /> were never implemented for configSections and sectionGroups because of the difficulty involved attempting to merge different definitions of the same section-handlers and section groups.
Hence the path workaround. You could also set up the applications so they are not related in terms of hierarchy, if this is critical
I have found that adding enableConfigurationOverride="false" to the application pool definition fixes this problem.
From the MSDN docs:
Optional Boolean attribute. When true, indicates that delegated settings in Web.config files will processed for applications within this application pool. When false, all settings in Web.config files will be ignored for this application pool.The default value is true.
There are two methods of doing this, where ChildApplicationName should be replaced with the value of your application pool name.
Method 1 (preferred/advised):
Execute the following command in appcmd in Administrator mode:
appcmd.exe set config -section:system.applicationHost/applicationPools /[name='ChildApplicationName'].enableConfigurationOverride:"False" /commit:apphost
Method 2:
The second involves directly editing the %windir%\System32\inetsrv\config\applicationHost.config file allows the application to effectively ignore the parent application. For various reasons, I don't advice doing this, but I leave this here for posterity.
In order to set this, do a search for your child application pool name. It should be under the xpath. /configuration/system.applicationHost/applicationPools.
<configuration>
<system.applicationHost>
<applicationPools>
...
<add name="ChildApplicationName" enableConfigurationOverride="false" />
...
<applicationPools>
<system.applicationHost>
<configuration>

Add more than one relative path in webconfig appSetting in asp.net

How can i specify more than one relative file path in appSetting path attribute in asp.net web.config file. where my appsetting keys are residing in two different file .
<appSettings file="Web.User.config">
</appSettings >
You cannot reference more than one file path for appSettings. appSettings is a section and you cannot have more than one of those. However, you can add a new section which works like the appSettings section. Example:
<configuration>
<configSections>
<section name="CustomConfig" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</configSections>
....
<CusTomConfig>
<add key="Key1" value="Value1"/>
</CustomConfig>
Then, you can access that section with:
NameValueCollection settings = (NameValueCollection)ConfigurationManager.GetSection("CustomConfig");
A second option is using a Custom Configuration Section. This will require some boilerplate code (as shown in the MSDN documentation) but you will be able to access setting values with properties, rather than referencing them with strings like settings["Key1"].

Mono with SQL Server Membership Provider?

Apparently Mono replaces references to SQL Server membership provider with sqlite membership provider (see ASP.NET_Settings_Mapping). Is there any way to convince Mono to use SQL Server for the membership provider?
When I try to log in to my web app, I get the following:
System.Configuration.Provider.ProviderException: Operation aborted due to an exception (see Trace for details).
at System.Web.Security.SqliteMembershipProvider.ValidateUser (string,string) <0x003bb>
at DirectMail.Controllers.AccountMembershipService.ValidateUser (string,string) [0x00000] in [file].cs:404
at DirectMail.Controllers.AccountController.ValidateLogOn (string,string) [0x00040] in [file].cs:346
at DirectMail.Controllers.AccountController.LogOn (string,string,bool,string) [0x00000] in [file].cs:79
at (wrapper dynamic-method) System.Runtime.CompilerServices.ExecutionScope.lambda_method (System.Runtime.CompilerServices.ExecutionScope,System.Web.Mvc.ControllerBase,object[]) <0x001c1>
at System.Web.Mvc.ActionMethodDispatcher.Execute (System.Web.Mvc.ControllerBase,object[]) <0x00028>
at System.Web.Mvc.ReflectedActionDescriptor.Execute (System.Web.Mvc.ControllerContext,System.Collections.Generic.IDictionary`2<string, object>) <0x0015b>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod (System.Web.Mvc.ControllerContext,System.Web.Mvc.ActionDescriptor,System.Collections.Generic.IDictionary`2<string, object>) <0x00036>
at System.Web.Mvc.ControllerActionInvoker/<InvokeActionMethodWithFilters>c__AnonStoreyB.<>m__E () <0x00092>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (System.Web.Mvc.IActionFilter,System.Web.Mvc.ActionExecutingContext,System.Func`1<System.Web.Mvc.ActionExecutedContext>) <0x00125>
The top of the file /usr/local/etc/mono/4.0/settings.map on one Debian Linux machine is:
<?xml version="1.0" encoding="utf-8" ?>
<settingsMap>
<map sectionType="System.Web.Configuration.MembershipSection, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
mapperType="Mono.Web.Util.MembershipSectionMapper, Mono.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"
platform="Unix">
<!-- The 'what' tag specifies which region of the section to modify. The 'value' attribute value is mapper-specific and is not defined here. It can be
any expression understood by the mapper to designate the section region to modify.
-->
<what value="providers">
<!-- 'what' can contain any number of occurrences of any three elements:
replace - replace the designated region
add - add a new entry to the region
clear - clear the region
remove - remove the designatedregion
The attributes to any of the above are freeform and are not processed by the mapper manager. They are stored verbatim for the
mapper to peruse.
-->
<replace name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqliteMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqliteServer" />
</what>
</map>
<!-- ... -->
On the ASP.NET Settings Mapping page that you linked to, in the section titled "Inhibiting the settings mapping", it says that adding:
<appSettings>
<add key="MonoAspnetInhibitSettingsMap" value="anything"/>
</appSettings>
to your app's Web.config file will disable settings mapping. I found, however, that value "anything" does not work. If I use the value "true" instead, then it does:
<appSettings>
<add key="MonoAspnetInhibitSettingsMap" value="true"/>
</appSettings>
This must be a misconfiguration because an implemented sqlmembershipprovider exists for Mono 2.0. It is using a DBProviderFactory to obtain a connection. A SqlClient implementation is also there so that only leads to the conclusion that the web.config for the website is not correct, which is not unthinkable because sqlclient and sqlite almost looks the same in an overcrowded web.config.
If anyone can post that one, that might clarify the problem at hand.

Custom Configuration Sections

I am currently trying to implement a Custom Configuration Section in a project I am busy with and no matter what I try I keep getting the error below:
{"An error occurred creating the configuration section handler for pageAppearanceGroup/pageAppearance: Could not load type 'Samples.AspNet.PageAppearanceSection' from assembly 'System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. (E:\Three Nine Developments\lastfm\msdn\msdn\bin\Debug\Samples.Aspnet.vshost.exe.config line 6)"}
I have copied the code from this MSDN Artricle:
http://msdn.microsoft.com/en-us/library/2tw134k3.aspx
I still get the same error.
I have tried the all the advice/guide in the following articles but to no avail.
http://www.evanclosson.com/devlog/bettercustomerrorsinaspnetcustomconfigurationsection
Link
This must be something stupid that I am missing.
I am running Vista, could that be a problem? some obscure security setting?
<configuration>
<!-- Configuration section-handler declaration area. -->
<configSections>
<sectionGroup name="pageAppearanceGroup">
<section
name="pageAppearance"
type="Samples.AspNet.PageAppearanceSection"
allowLocation="true"
allowDefinition="Everywhere"
/>
</sectionGroup>
<!-- Other <section> and <sectionGroup> elements. -->
</configSections>
<!-- Configuration section settings area. -->
<pageAppearanceGroup>
<pageAppearance remoteOnly="true">
<font name="TimesNewRoman" size="18"/>
<color background="000000" foreground="FFFFFF"/>
</pageAppearance>
</pageAppearanceGroup>
</configuration>
My guess is that you've copied the code, but you have different assembly names. Posting the config will help.
I would also fully quality your type in the config (something that sample doesn't show). Something like...
<section name="MySection" type="My.Assembly.Type, My.Assembly" />
You should also check out Jon Rista's three-part series on .NET 2.0 configuration up on CodeProject.
Unraveling the mysteries of .NET 2.0 configuration
Decoding the mysteries of .NET 2.0 configuration
Cracking the mysteries of .NET 2.0 configuration
Highly recommended, well written and extremely helpful!
Marc
Please try with the following code:
<configSections>
<sectionGroup name="pageAppearanceGroup">
<section name="pageAppearance" type="Samples.AspNet.PageAppearanceSection,Samples.AspNet" allowLocation="true" allowDefinition="Everywhere" />
</sectionGroup> <!-- Other <section> and <sectionGroup> elements. -->
</configSections>
Please try with this
<configSections>
<sectionGroup name="pageAppearanceGroup">
<section name="pageAppearance"
type="Samples.AspNet.PageAppearanceSection,Samples.AspNet"
allowLocation="true"
allowDefinition="Everywhere" />
</sectionGroup>
<!-- Other <section> and <sectionGroup> elements. -->
</configSections>
Thanks,
Vedi
So it turns out that when you create a project in Visual Studio, it automatically defines a root namespace (the name of the project by default) for the project. Thus you must include that root namespace in the section type as well as any custom namespaces you defined within your settings class.
For example, in the case of the original poster a working configuration for them may have looked something like this:
<section name="MySection" type="ROOT_NAMESPACE.Samples.AspNet.PageAppearanceSection, NAME_OF_ASSEMBLY" />
Where ROOT_NAMESPACE and NAME_OF_ASSEMBLY are defined in the project properties as shown in this snapshot of my project.
In my particular case, I did not explicitly define namespaces in my project. Thus my section configuration setting just had the root namespace, the name of the settings class, and the name of the assembly, as such;
<section name="programSettings" type="ShipmentImport.ProgramSettings, ShipmentImport" />
I know its a couple years late, but I hope it keeps somebody else from spending hours on this like I did.

Resources