ASP.NET MVC 4 - Application not accepting new connection string - AppHarbor Deploy Issue - asp.net

I'm currently working on an ASP.NET MVC 4 project that is using Entity Framework 4.3 with a CodeFirst approach using simple POCO classes. Also, I'm using SQL Server Express as the development database.
After building my classes and setting the connection string, I ran my project and it generated a SQL Server Express database for me with no problems.
The problem though, is that I am trying to deploy to AppHarbor and I'm having an issue with the connection string. AppHarbor requires that you install SQL Server as an 'Add-On' and configure the connection string to have an alias that will inject their Sequilizer connection string into the project that you push from GitHub.
Here is their documentation on how this works: http://support.appharbor.com/kb/add-ons/using-sequelizer
I believe I have all of this setup correctly, but there seems to be a problem with how my app is reading the connection string.
Here is the development connection string that I am using on my local machine:
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-FranchiseManager-201275154247;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Here is what the AppHarbor Sequilizer connection string looks like:
<connectionStrings>
<add
name="DefaultConnection"
connectionString="Server=0691298f-d461-40cc-86d6-a089016ba88d.sqlserver.sequelizer.com;Database=<removed hash value>;User ID=<removed hash value>;Password=<removed hash value>;"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
The first connection - generated locally by my EF - works just fine. The second - created by Sequilizer - is not being read by my application.
However - I can connect to the Sequilizer database through SQL Server Management Studio. So it must be my app right?
In order to trouble shoot my deployment to AppHarbor, I hard-coded their connection string into my app instead of the one auto-generated by EF and tested on my local machine.
Here's what I did:
Replaced the connection string in Web.config with the one AppHarbor
provided,
Cleaned the solution,
Rebuilt the solution
But when I ran the application, it is still utilizing the original database generated by EF - which must mean that it is still reading the old connection string.
It seems like changing the connection string is not enough. What else in my application should I change in order to replace the connection string?
Any advice is appreciated - thanks!
EDIT
Here is my DbContext class:
public class FranchiseManagerContext : DbContext
{
public DbSet<FranchiseSet> FranchiseSets { get; set; }
public DbSet<Franchise> Franchises { get; set; }
}
This works as-is with the connection string named "DefaultConnection".
How does EF know to match the DbContext with the connection string in this scenario, but it cannot do it if you change the name of the string?
UPDATE
I think I know what it is now from this SO answer: What is the point of "Initial Catalog" in a SQL Server connection string?
It looks like the Initial Catalog attribute is specifying the particular database to be used when Entity Framework first kicked in.

You have to specify the name of the connectionstring you want your DbContext to load. It has no way to magically guess that you want it to use the one called DefaultConnection. There's a heuristic that says that if no name is specified, it'll look for for a connectionstring with name set to the name of the class that inherits from DbContext. Ie. if you have:
MyAwesomeDatebase : DbContext
... then Entity Framework will work out of the box with this:
<add name="MyAwesomeDatebase" connectionString="blah" providerName="System.Data.SqlClient" />
... but if you have:
<add name="DefaultConnection" connectionString="blah" providerName="System.Data.SqlClient" />
... then it won't work because Entity Framework has no way of knowing that MyAwesomeDatebase goes with DefaultConnection.
To make that work, do this:
public class MyAwesomeDatebase : DbContext
{
public MyAwesomeDatebase() : base("DefaultConnection")
}
... and you're golden.

Ok, I think I've finally got this working.
I can't find this anywhere in the AppHarbor documentation (perhaps it is something specific to .net mvc?), but the connection string must have the same name as my DbContext class.
I found some hints on this by looking at some other questions on SO.
For anyone else that may run into the same issue:
be sure the name attribute of the ConnectionString in Web.config is the same name as your DbContext Class
Commit and push the project to your repo
Make sure the Alias name on AppHarbor is the same name as your connection string
Deploy the new build on app harbor after step 3 (this is necessary to pick up the new connection string name)
After doing that my app picked up the Sequilizer database and it's now working fine.

Related

.NET Core Azure Function and Entity Framework 6 not properly interpreting ConnectionStrings from local.settings.json

I have a .NET 4.x library that is being referenced both by a ASP.NET 4.x webapp and a .NET Core 3.x Azure Function. In this library is an EF6 DbContext-derived class with a constructor like this:
public MyContext() : base("DefaultConnection") { }
And of course there's a "DefaultConnection" ConnectionString defined in the dotnet4 webapp's web.config. This connection string points to a local instance of SQL Express, and looks like this:
<add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
Works great, always has.
Now we have the Azure Function which we're trying to test locally. The ConnectionStrings section in the local.settings.json looks like this:
"ConnectionStrings": {
"DefaultConnection": "Data Source=.\\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True;MultipleActiveResultSets=True"
}
I've also tried strongly typed versions of the ConnectionString, explicitly defining the ConnectionString and ProviderName separately to no avail.
The problem I'm running into is that when running in the context of an Azure Function/ under dotnetcore in general, connection string names are not recognized when passed into the constructor, and instead are treated as the default catalog. This is the connection string that the Function ultimately dreams up:
"Data Source=(localdb)\\mssqllocaldb;Initial Catalog=DefaultConnection;Integrated Security=True;MultipleActiveResultSets=True"
...despite no reference to localdb anywhere in the codebase. If I change the DbContext constructor to this:
public MyContext() : base("RatFink") { }
The connection string used by the context is:
"Data Source=(localdb)\\mssqllocaldb;Initial Catalog=RatFink;Integrated Security=True;MultipleActiveResultSets=True"
If I pass the actual connection string into the call to base() it is recognized as such and everything works as expected, but this requires code changes to the referenced library which is less than ideal.
Why is the connection string name not being recognized and read from the local.settings.json under the context of an Azure Function/.NET Core and how can I resolve?

Unable to find the requested .Net Framework Data Provider. It may not be installed

I am having problem in running my ASP.Net MVC project which is an admin project. It connects with a sql server database to fetch record. When I try to build and run, I am welcomed with this error: "Unable to find requested .Net Framework Data Provider. It may not be installed".
Here is the link to this error.
I have tried many solutions available on stackoverflow but none of them worked for me that's why I am posting this question here again. I tried changing the Target Framework version in Properties of project to all the available versions but all in vain. Here is the screenshot of my Global.asax.cs file which is causing this exception.
Below is the connection string of my project:
<add name="AlkhaleejEntities" connectionString="metadata=res://*/Models.Model1.csdl|res://*/Models.Model1.ssdl|res://*/Models.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=Alkhaleej;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
Connection string provided above indicates EF connection provider being used:
connectionString="metadata=res:///Models.Model1.csdl|res:///Models.Model1.ssdl|res://*/Models.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=Alkhaleej;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"
Note that SimpleMembershipProvider can't use EF provider connection string (see this post) due to usage of SqlClient provider instead of EntityClient, hence it requires SQL Server connection string to interact with database.
Try open Server Explorer => Data Connections => right click your server connection, select Properties => add provided SQL Server connection string something like this one (leave EF connection string part as is, just add SqlClient provider connection string):
<add name="DefaultConnection" connectionString="Data Source=.;Initial Catalog=Alkhaleej;Integrated Security=True" providerName="System.Data.SqlClient" />
Then, change connectionStringName parameter on WebSecurity.InitializeDatabaseConnection method inside SimpleMembershipInitializer class to SQL Server connection string name as given below:
public class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
// other code part
if (!WebSecurity.Initialized)
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "Email", autoCreateTables: true);
}
}
}
NB: The ideal setup for EF projects should include at least one SqlClient connection string and one EntityClient connection string, which may serve different providers with same target database.
Similar issues:
SimpleMembershipInitializer won't initialize
Unable to find the requested .Net Framework Data Provider. (SqlClient)
Can SimpleMembership and Entity Framework share a connection string?

Setting EF Connection String in Azure Web App

We have an ASP .NET (MVC) app and are using Entity Framework 6 to connect to our databases. The DbContext is constructed in a standard way and it loads the connection string on our behalf. The generated code looks like this:
public partial class MyContext : DbContext
{
public MyContext(string connectionName)
: base("name=" + connectionName)
{
}
}
We set the connection string in a local web.config also in a standard way:
<configuration>
<connectionStrings>
<add name="DefaultConnection"
connectionString="metadata=...;provider connection string="...""
providerName="System.Data.EntityClient" />
When we publish the app to Azure we navigate to the Azure Portal, then to the Web App's Settings, then to the list of Connection Strings. There we add the EF connection string that we had used locally. When we restart and visit the app we get a run-time error depending on the type of connection string we choose.
For a Custom type we get the following run-time error:
Keyword not supported: 'data source'.
For SQL Server or SQL Database we get the following run-time error:
Keyword not supported: 'metadata'.
This really seems like a straightforward story so we are wondering what is going wrong.
The problem is the escaped quotes: ".
The connection strings in web.config have quotes escaped because they are serialized in an XML attribute. When entering a connection string in the Azure portal you should provide the raw unescaped string. Something like this:
metadata=...;provider connection string="Data Source=..."
David Ebbo's answer is good for confirming that the Environment is set up as you expect. It is also helpful to pay attention to the .pubxml file when publishing via the wizard in Visual Studio: it will try to populate connection strings as well.
'custom' should be correct here. In that case, the providerName is left unchanged, so if you have System.Data.EntityClient in your config, that should remain after the Azure runtime changes it.
Try going to Kudu Console and click on Environment to make sure the conn string looks correct there.
If you have this line in web.connfig
<add name="Entities" connectionString="metadata=res://*/TestDB.csdl|res://*/TestDB.ssdl|res://*/TestDB.msl;provider=System.Data.SqlClient;provider connection string="Data Source=XXXXXXXX.database.windows.net,1433;Initial Catalog=YourDB;User ID=YourUser;Password=XXXXXX"" providerName="System.Data.EntityClient" />
Add this in azure portal:
Name Column => Entities
Value Column => metadata=res://*/TestDB.csdl|res://*/TestDB.ssdl|res://*/TestDB.msl;provider=System.Data.SqlClient;provider connection string="Data Source=XXXXXXXX.database.windows.net,1433;Initial Catalog=YourDB;User ID=YourUser;Password=XXXXXX"
"Custom" - In the drop selection box
Make sure (as stated in first answer) to replace " with "
Just recording my own experiences in addition to answers already recorded here
This was my final connection string (on mutliple lines for clarity)
metadata=res://*/Models.mBT.csdl|res://*/Models.mBT.ssdl|res://*/Models.mBT.msl;
provider=System.Data.SqlClient;
provider connection string="
Data Source=tcp:myazureserver.database.windows.net,1433;
Initial Catalog=databasename;
User ID=z#myazureserver;
Password=xyz"
To convert from a "normal" connection string to one that is accepted by EF:
The connection string type in the application settings has to be "other" not "SQL Azure"
The connection string value automatically replaces anything published in web.config
The metadata name Models.mBT.csdl (and the other two) comes from this:
Firstly, mBT is the name of my .edmx file
With regards to the Model. bit, see the answer from #leqid here: MetadataException: Unable to load the specified metadata resource
You can inspect your obj directory and see these three metadata files are in a subfolder called Models, so you need to prepend with Models.

problem in connectionstring in asp.net

private string conString = "Data Source=173.56.33.6;Database=musicapp;User ID=guest;Password=guest";
I was working on local database at that time my application was successfully interacting with mysql database.when put the database on server, my application still taking the old connection string and data is stored in local database and not on server.
what is wrong?
I'd remove hard coded connection strings all together. There is a dedicated section of your config file for this very purpose:
<connectionStrings>
<add name="MusicApp" connectionString="Data Source=173.56.33.6;Database=musicapp;User ID=guest;Password=guest;" />
</connectionStrings>
Which you can then read out:
string connection = ConfigurationManager.ConnectionStrings["MusicApp"].ConnectionString;
I think your problem is that you have the connection string hard-coded in your code (as a private string that you show above). A much better way is to store it in the config file, use Settings in VS and select ConnectionString as type.
Make sure whether you updated your connection string when you transfered your DB to server. In any case it is best to store connection string in web.config, so that you can modify it when ever your db is changed or transferred to another location. This change in connection string in your web.config wouldn't require you to rebuild your application. Although if your connection string is hard-coded in code, then you would require to rebuild your application when ever you change the connection string.
if Data Source=173.56.33.6; is the location of your server database try this instead Data Source=\173.56.33.6;

ASP.NET EFCodeFirst not using correct connection string

I am trying to publish a website using ASP.NET MVC3 EF and CODEFIRST with a SQL Server 2008 backend. On my local machine I was using a sql express db for development, but now that I am pushing live, I want to use my hosted production database. The problem is that when I try to run the application, it is still using my local db connection string. I have completely removed the old connection string from my web.config file and am using the <clear /> tag before creating the new connection string. I have also cleaned the solution and rebuilt, but somehow it is still connecting to the old db. What am I missing?
This is the new connection string:
<connectionStrings>
<clear />
<add name="CellularAutomataDBContext"
connectionString=" Server=XXX;
Database=CellularAutomata; User ID=XXX; Password=XXX; Trusted_Connection=False"
providerName="System.Data.SqlClient" />
</connectionStrings>
UPDATE
When I debug and look at the DBCONTEXT object, this is what is showing up for its connection:
Data Source=.\\SQLEXPRESS;Initial Catalog=CellularAutomata.Models.D1K2N3CARuleDBContext;Integrated Security=True;MultipleActiveResultSets=True"
I am unsure why this is happening because I cannot find it being set to this anywhere. Also, under configuration it says LazyLoadingEnabled = true, I assume this may be part of the problem, maybe it is not loading the new connection string. Where do I change these parameters?
UPDATE 2
EFCodeFirst is using a default connection string, I can't figure out how to get it to accept the connection string that I specify in the web.config file.
So, When using EF CodeFirst, there is a default connection string that it uses. If you want to be able to use a custom connection string, there are a few parameters guidelines that you must follow.
name ="this must match the name of your database context class"
connectionString="Server=yourserverurl; Database=yourdatabasename; User ID=youruserid;
Password=yourpassword; Initial Catalog=the name of the database to use;
Trusted_Connection=False"
providerName="System.Data.SqlClient"
So far this is working for me.
The connectionString you show is not an EF connection string. The EF won't use it. So you're changing the wrong thing.
An EF connectionString will include providerName="System.Data.EntityClient"
It will look for the same name as your context and depending on what else you
are using other names as well. I usually use the following for controlling
specific features with either the same or specific connection strings
(I keep app services in a different db for example so EFCF can drop tables as needed):
<connectionStrings>
<add name="MyAppContext" .../>
<add name="ApplicationServices" .../>
<add name="DefaultConnection" .../>
</connectionStrings>

Resources