EntityFramework connection string in referencing project's web.config - c#

I have two projects in my solution: an ASP.NET MVC web app project with a web.config per environment (production/UAT/dev) and another DAL class library project referenced by the web project that uses EntityFramework Database First to handle persistence. At the moment, the DAL class library project has its own App.Config that specifies the connection string to be used.
I require different connection strings (or rather, different data source) for the different environments.
How would I go about moving the connection strings to the web.config in the the web project and referencing them from the DAL project at runtime?
The auto-generated EF Model.Context.cs code that currently references the connection string name is [name changed for anonymity]:
public EodActivityEntities()
: base("name=DatabaseNameEntities")
{
}

Your application will only ever read a single app.config or web.config at run time which will be the one from your start-up project.
Therefore if you have the following in your DAL:
public EodActivityEntities()
: base("name=DatabaseNameEntities")
{
}
... and you run your web application as your start-up project, it will pick up the connection string with name DatabaseNameEntities from that project's web.config, ignoring what is in your DAL app.config. So it's already doing that for you. Therefore I would say that you shouldn't need to have your connection string in your DAL's app.config file at all.
Now, for the different environments you want different connection strings. Create new Solution Configurations for your environments DEV, UAT & LIVE and you can use web.config transformations (info here and here) and it will build with the correct connections strings.

I would recommend passing the connection string in the constructor of your context. The base constructor created by EF takes a string and can either be a named value from a configuration file or simply the connection string itself.
Then move your connection strings per environment to the MVC project where you can instantiate the context using values in it's web.config
var connectionString = WebConfigurationManager.AppSettings["connection"];
var context = new EodActivityEntities(connectionString);
Coulton is correct in that only one configuration file will be loaded, and a solution could be to name the connection strings the same so that the web.config will load when you run the application. However, this is spreading your configuration around rather than pushing that to the context root of the application.

When you reference your DAL project from your Web project, the built DAL.dll should automatically be copied into the /bin folder of your Web project at the time the Web project is built. First, check that is indeed happening. If not, look at the Web project References, find your DAL project in the list and view the properties. CopyLocal should be set to True.
When your Web project is running, any reference made by your DAL to settings that would have come from your DAL's app.config, will instead come from your Web app's web.config, as the DAL will be running under the context of the Web application.
So you are right, that you need to add settings to your web.config.
The best way to utilise different values for different environments is to use web.config transforms. In a Web application, you may already have a couple of these as child solution files sat under your web.config (web.debug.config & web.release.config). Visual Studio will apply these transformations when publishing. We typically have a publish profile for each environment and a matching transform file for each environment, but only one actual web.config file with all the default (untransformed) settings in.
You didn't mention which version of Visual Studio you are using, but this article may help you along the way:
http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/web-config-transformations
This explains further: http://go.microsoft.com/fwlink/?LinkId=125889

Related

Using a web.config file in .Net Core Web API

We're building a .net core web api application at the moment and so far it's been great to work with. However we have an issue with our deployment server (Team Studio) being unable to replace the DB connection string inside the appsettings.json file. Is it possible to solve this issue by putting the connection string in the old web.config format so that Team Services can do a replacement? I tried creating one but I'm unable to access the connection string from it using System.Configuration
The way appsettings.json is supposed to work is that it should only contain environment-neutral config. Anything specific to a particular environment, such as connection strings, should go into appsettings.{Environment}.json. That file is then loaded in based on the ASPNETCORE_ENVIRONMENT environment variable set on the server you're deploying to. In other words, you shouldn't need to replace anything. Just deploy both appsettings.json and appsettings.{Environment}.json and make sure that the ASPNETCORE_ENVIRONMENT variable is set appropriately.
Fortunately, web.config was removed from .net core. Only one thing that I can recommend is to create power shell script that will replace connection strings in your appsettings.json, and call it using team city agent.

How to customize class library config settings across projects & clients

Apologies if this has been asked before; after two days of searching I can only find partial answers that don't fully relate to my situation, and are difficult to follow with my lack of experience.
I have a solution that contains four projects:
Class library (containing database connection strings, email server settings, plus lots of other settings)
Web application (web forms)
Web application (MVC)
Web API
Projects 2,3 & 4 all reference the class library, and use the database connection strings, etc, to function. These projects also contain their own additional settings in web.config, bespoke to that project.
Everything works great so far... However, I now need to publish client-specific versions of my solution, e.g. the solution for ClientABC requires different settings for each project than for ClientXYZ. All other aspects remain the same, it is simply the config settings across the four projects that need to change.
From my research, I hit upon something called SlowCheetah which transforms the config files based on the publish profile. That sounded promising, but then I get this problem, where the class library settings aren't pushed into the other projects. I can see bits of useful info in this question, but don't have the experience to apply it to my problem. I'd rather not duplicate the settings into respective project's config file if possible, as that feels messy.
Can anyone please offer me some help as to what's best here? I don't even know if I'm taking the right approach, but am pretty sure I can't be the first ask this?
but then I get this problem, where the class library settings aren't pushed into the other projects
you have to keep in mind that the configuration file is readed by the SturtUp application, your client. Class Library can't run directly, but inside a WebApp or WinApp or ConsoleApp
So, any settings that you put in your ClassLibrary configuration file must be copied in the configuration file of your WebApp.
Generally, I copy some settings from app.config to web.config but, if you search on internet, you can find a method to automate this operation.
I now need to publish client-specific versions of my solution
You can create many configuration profile and use a web.config transformation:
From ToolBar or Build Menu, select Configurazion Manager...
Create all configuration you need for clients
Now you can see different web.configuration files
Now you can specify different configurazion transformation for your ClientABC, ClientXYZ and publish them with specific configuration
EDIT:
So, you can adopt this solution for your Class Library too, or external config file, and include external file in your web.config: External Config

How I prevent to get latest or check-in a specific file automatically in Team Foundation Server?

I work on a team that works on a project. I change my project web config file to set a specific connection string but when I check-in or get latest version of project it changes to others connection strings. I have same problem in WCF Service references. appconfig and xsd files of service references always corrupted when I check-in or get latest version of program from tfs and I have to delete service references and add it again! How can I get rid of this?
We had the same issue on our project (with connection strings), and found a good solution: http://msdn.microsoft.com/en-us/library/ms254494(v=vs.110).aspx
By adding a connections.config file for each developer with his own connection string, we just needed to say that this file must not be a part of Source Control. Then in the web.config connectionString section, you just refer to the connections.config file.
Just be aware that you need to either transform your web.config or add the connections.config when publishing the site.
I know you can do the same about the appSettings section in the web.config.
How you do it with WCF, I don't know - but it sounds strange to me that your are not using the same WCF refence.
There are many solutions.
The team uses the same configuration (e.g. everyone uses localhost references)
You separate user from application settings (do not apply to all kind of settings nor projects)
Use transforms and solution configuration to map have per-environment setting
Use configSource to move config section in separate files that are not under version control
I do not think there is a perfect solution, but maybe you apply a mix of these. I strongly suggest to apply them in the stated order.

No connection string named 'MyEntities' could be found in the application config file

I am using entity framework and ASP.NET MVC 4 to build an application
My solution is split into two projects;
A class library that includes my data model (.edmx) file and a few custom interfaces
The 'container' MVC project that references the class library above
My problem is that when I attempt to use the 'MyEntites' DbContext I get the the following error:
No connection string named 'MyEntities' could be found in the
application config file.
I guess the problem has something to do with the fact that connection string lies within the app.config of the class library rather than the MVC project.
Does anyone have any suggestions?
Try copying the connections string to the .config file in the MVC project.
You are right, this happens because the class library (where the .edmx file) is not your startup / main project.
You'll need to copy the connection string to the main project config file.
Incase your startup / main project does not have a config file (like it was in my Console Application case) just add one (Startup project - Add New Item -> Application Configuration File).
More relevant information can be found here:
MetadataException: Unable to load the specified metadata resource
make sure that you make your project (with the DbContext) as startup
OR
Add to the project that is set as startup your connection string in the app.config (or web.config)
OR
Call the command like this
Update-Database -Script -ProjectName '<project name>' -StartupProjectName '<project name>' -ConnectionString 'data source=.;initial catalog=<db name>;integrated security=True;MultipleActiveResultSets=True' -ConnectionProviderName 'System.Data.SqlClient'
Then try again
You could just pass the connection string to EntityFramework and get on with your life:
public partial class UtilityContext : DbContext
{
static UtilityContext()
{
Database.SetInitializer<UtilityContext>(null);
}
public UtilityContext()
: base("Data Source=SERVER;Initial Catalog=DATABASE;Persist Security Info=True;User ID=USERNAME;Password=PASSWORD;MultipleActiveResultSets=True")
{
}
// DbSet, OnModelCreating, etc...
}
copy connection string to app.config or web.config file in the project which has set to "Set as StartUp Project" and if in the case of using entity framework in data layer project - please install entity framework nuget in main project.
As you surmise, it is to do with the connection string being in app.config of the class library.
Copy the entry from the class app.config to the container's app.config or web.config file
If you have multiple projects in solution, then setUp project as started where you have your truth App.config.
Add an App.Config file
Set the project as startup project.
Make sure you add the connection strings after entityFramework section:
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</configSections>
<connectionStrings>
<!-- your connection string goes here, after configSection -->
</connectionString>
It is because your context class is being inherited from DbContext. I guess your ctor is like this:
public MyEntities()
: base("name=MyEntities")
name=... should be changed to your connectionString's name
It also happens if the startup project is changed to the one, which does not have the connection strings.
Right Click Solution - click properties
Under Common Properties,select startup project
On the right pane select the project which
has the connection strings (in most cases, it will be MVC projects -
the project that starts the solution)
Yeah, it's silly. You can avoid copying the connection string by using a connection builder. VB.Net code (used in production, but slightly modified here, so treat as untested, happy to assist with any issues), where I have a serverName variable, a databaseName variable, I pass them into a method and have it generate the connection for me:
Dim EfBuilder As New System.Data.EntityClient.EntityConnectionStringBuilder("metadata=res://*/VMware.VmEf.csdl|res://*/VMware.VmEf.ssdl|res://*/VMware.VmEf.msl;provider=System.Data.SqlClient;provider connection string=""data source=none;initial catalog=none;integrated security=True;multipleactiveresultsets=True;App=EntityFramework""")
Dim SqlBuilder As New Data.SqlClient.SqlConnectionStringBuilder(EfBuilder.ProviderConnectionString)
SqlBuilder.DataSource = serverName
SqlBuilder.InitialCatalog = databaseName
EfBuilder.ProviderConnectionString = SqlBuilder.ConnectionString
Using vmCtx As New VmEfConn(EfBuilder.ConnectionString)
are you using more than one project on your solution?
Because if you are, the web config you must check is the one on the same project as de .edmx file
Add ConnectionString to MVC Project Web.config file
I've had this problem when I use multiple proyects, the start proyect with web.config and app.config for EntityFramework project.
for avoid this problem you must:
You need the connection string in the started *.config file.
You need have installed the EntityFramework DLL into your references
I have faced the same issue. I was missed to put connection string to startup project as I am performing data access operation from other layer. also if you don't have app.config in your startup project then add app.config file and then add a connection string to that config file.
I got this by not having the project set as startup, as indicated by another answer. My contribution to this - when doing Add-Migrations and Update-Database, specify the startup project as part of the command in Nuget Package Manager Console (do not include the '[' or ']' characters, that's just to show you that you need to change the text located there to your project name):
Enable-Migrations
Add-Migrations -StartupProject [your project name that contains the data context class]
Update-Database -StartupProject [same project name as above]
That should do it.
The connection string generated by the project containing the .edmx file generates the connection string, this would appear to be a holdover from the app.config sorts of files that were copied to the output directory and referenced by the executable to store runtime config information.
This breaks in the web project as there is no automatic process to add random .config information into the web.config file for the web project.
Easiest is to copy the connection string from the config file to the connections section of the web.config file and disregard the config file contents.
The best way I just found to address this is to temporarily set that project (most likely a class library) to the startup project. This forces the package manager console to use that project as it's config source. part of the reason it is set up this way is because of the top down model that th econfig files usually follow. The rule of thumb is that the project that is closest to the client (MVC application for instance) is the web.config or app.config that will be used.
Make sure you've placed the connection string in the startup project's ROOT web.config.
I know I'm kinda stating the obvious here, but it happened to me too - though I already HAD the connection string in my MVC project's Web.Config (the .edmx file was placed at a different, class library project) and I couldn't figure out why I keep getting an exception...
Long story short, I copied the connection string to the Views\Web.Config by mistake, in a strange combination of tiredness and not-scrolling-to-the-bottom-of-the-solution-explorer scenario.
Yeah, these things happen to veteran developers as well :)
This problem happen when you are using Layers in your Project and defined or install Entity frame work in DataLayer and try to run your Project
So to overcome from this problem copy the connection string from the layer where the Edmx file is there and paste the connection string in main web.config.
Add a connection string in the root web.config file of 'container' MVC project that references the class library as following:
<connectionStrings>
<add name="MyEntities" connectionString="complete connection string here" providerName="System.Data.SqlClient" />
</connectionStrings>
If you do not want to use "MyEntities" as connection name then change it as you wish but make the following change in your MyEntities DbContext class:
MyEntities: DbContext
{
public MyEntities():base("Name-Of-connection-string-you wish to connect"){ }
}
Reason for this error is, If we will not specify the name of connection string Or connect string in derived class of DbConext(In your case it is MyEntities) then DbContext will automatically search for a connection string in root web.config file whoes name is same as derived class name (In your case it is My Entities).
I had this problem when running MSTest. I could not get it to work without the "noisolation" flag.
Hopefully this helps someone. Cost me a lot of time to figure that out. Everything ran fine from the IDE. Something weird about the Entity Framework in this context.
Regular migrations
There are two options - the first one that everyone here has suggested is to ensure that the connection string is in the Web.config file of the project. When working with connection strings from Azure application settings, that means overwriting your Web.config values with the Azure values.
Azure or automatic migrations (programmatic)
There's a second option available if you're running migrations programmatically, that allows you to run migrations using a connection string that's obtained dynamically (or via Azure application settings) without storing it in Web.config:
When setting the configuration's TargetDatabase, use the DbConnectionInfo constructor that takes a connection string and a provider name instead of the constructor that takes just a connection name. If your connection string doesn't have a provider name and you're using SQL Server / Azure SQL then use "System.Data.SqlClient"
This could also result in not enough dll references being referenced in the calling code. A small clumsy hack could save your day.
I was following the DB First approach and had created the EDMX file in the DAL Class library project, and this was having reference to the BAL Class library, which in turn was referenced by a WCF service.
Since I was getting this error in the BAL, I had tried the above mentioned method to copy the config details from the App.config of the DAL project, but didn't solve. Ultimately with the tip of a friend I just added a dummy EDMX file to the WCF project (with relevant DB Connectivity etc), so it imported everything necessary, and then I just deleted the EDMX file, and it just got rid of the issue with a clean build.
There is a comment on the top answer by #RyanMann that suggests:
Store your connection strings in one config file, then reference them in other projects by <connectionString configSource="../ProjectDir/SharedConnections.config" />
This is a fantastic suggestion!
It also works to share connection strings between App.config and Web.config files!
Anyone wanting to follow this suggestion, should head on over to this SO answer.
It has a really great step-by-step guide on sharing connection strings among multiple projects in a solution.
The only caveat is that configSource must exist in the same directory or a sub-directory. The link above explains how to use "Add as Link" to get around this.
I had this error when attempting to use EF within an AutoCAD plugin. CAD plugins get the connection string from the acad.exe.config file. Add the connect string as mentioned above to the acad config file and it works.
Credit goes to Norman.Yuan from ADN.Network.
If you are using an MVVM model, try to copy the connection strings to all parts of your project.
For example, if your solution contains two projects, the class library project and the wpf project, you must copy the connection strings of the backend project (library class porject) and place a copy in the App.config file of the wpf project.
<connectionStrings>
<add name="DBEntities" ... />
</connectionStrings>
Hope it's helpful for you :)
Add Connectoinstrnig in web.config file
<ConnectionStiring> <add name="dbName" Connectionstring=" include provider name too" ></ConnectionStiring>

DLL settings from another DLL

I have a MVC project that uses foo.dll, but that foo.dll uses smu.dll so basically I never reference smu.dll within my MVC project. The problem I´m faced with is that within my MVC project I want to be able to store ssettings in web.config so that smu.dll will read.
We have tried to use both applicationsettings and appsettings without effect, when I refernce smu.dll directly from MVC or any other program it picks up the settings without a problem. Do settings for smu.dll have to go into foo.dll app.config?
EDIT
Hello again friends, and thank you for your answers.
I found out what I was doing wrong after I read the comments. In MVC there is a web.config within the Views-folder and one web.config in the root of the project. When I used sectionGroup and applicationSettings in the "Views"-web.config the config was not read by the smu.dll. I then changed the smu.dll to read appsettings instead, whereas I then put the appSettings into to "root"-web.config, then the config file was read by the dll. I hope this makes sense but I am new to this and am still learning.
Anyway, this is finally working now :)
So, you have an MVC project, and two class libraries (foo & smu) ?
MVC -> Foo (via project reference)
Foo -> Smu (via project reference)
within AppSettings of web.config, you have a setting that smu should pick up?
Shouldn't Smu just accept a param, but not care where it comes from e.g.
if Smu was a data-access class, and it needed a connection string - all it needs to allow the user to do is send it a connection string? so, you could then send that from Foo (as this class can access your config settings) ?

Categories

Resources