How to configure entity framwork (Model First ) on microsoft azure? - azure

I was using EntityFramwok (code First) in my application, but for some cause i have to change entityframwork approch to Database First. i have configured the project on local successfully, when published the code to microsoft azure server and tried to login in my application it throws an exception: " The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715 "
I have searched about it on google but can't found any clue, seems i am the only person who got this exception :( does anybody knows about this. I am new to azure so don't know how to change the entityframwork approach there. any help or suggestions will be appreciated :)

I just deployed a database first project to Azure and ran into the identical error. Seems like there is a lot more information when googling now than there was when you asked this question. Regardless, none of it was entirely on point for me though and I had to experiment to come up with the solution.
Here's my scenario:
My database first DB is hosted on Azure as well and the connection string that Azure recommends for ADO.NET is what I put in my Web.Release.config transformation entries. I have two connection strings, one is the default connection and the other is the one that is used for the db first project. The solution was to use the same (functioning) content from the Web.config connection string and only replace the inner portion with Azure db connection string. I was cut & past happy at first and just wiped out the full content of the connection string leading to the error.
Lot's of the info within the connection string is particular to your project and the db first entities you have created in the project. Here are a couple examples from what I have:
You're Web.config should have connection strings for you local dev environment (chances are these were created for you by the DB first wizard):
<configuration>
...
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebRole1-20150218073037.mdf;Initial Catalog=aspnet-WebRole1-20150218073037;Integrated Security=True" providerName="System.Data.SqlClient" />
<add name="DbFirstModelEntities" connectionString="metadata=res://*/Models.DbFirstModel.csdl|res://*/Models.DbFirstModel.ssdl|res://*/Models.DbFirstModel.msl;provider=System.Data.SqlClient;provider connection string="data source=(localdb)\ProjectsV12;initial catalog=DbFirstData;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
...
</configuration>
Notice how the dbfirst connection string starts out with a bunch of meta data about the db models. This stuff is important!!
Next comes the correct Web.Release.config connection string transformation (just posting the DB first one, but you'd need to do something similar for any others that you have):
<connectionStrings>
<add name="DbFirstModelEntities"
connectionString="metadata=res://*/Models.DbFirstModel.csdl|res://*/Models.DbFirstModel.ssdl|res://*/Models.DbFirstModel.msl;provider=System.Data.SqlClient;provider connection string="Server=tcp:<yourdatabesserver>.database.windows.net,1433;Database=DbFirstData;User ID=<user>;Password=<password>;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
So long story, if you're encountering this error after publishing to azure: go check your transformations and make sure you're not removing all that important meta data!

While configuring your website and database on the azure server you have to define a connection string and the name of the connection string should not be the same as connection string name in your web.config file. I just did rename the connection string name in my web.config and problem solved. :)

Related

Azure App Service Application Settings Ignored, Using web.config Instead

I recently deployed an ASP.Net Web API project to our Azure App Service test slot but started receiving an error when making requests to the API endpoints. Through remote debugging, it became clear that the app was extracting my dev connection strings from the deployed web.config file.
The connection strings are supposed to come from the Application Settings we set up via the Azure Portal - and, in previous deployments, they were - but that's not the case.
Why would this happen and what can be done to ensure the correct behaviour occurs? We absolutely don't want our production database secrets being put into GIT via the web.config...
I recently experienced the same problem and fixed it:
In Azure App Services, the machine-wide web.config file is located at D:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config.
This file differs to a normal machine-wide web.config file because it has this extra element:
<system.web>
...
<compilation>
<assemblies>
<add assembly="EnvSettings, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
...
</assemblies>
</compilation>
</system.web>
The EnvSettings.dll assembly is located inside D:\Program Files\IIS\Microsoft Web Hosting Framework (unfortunately this directory is access-controlled and I can't get into it).
But EnvSettings.dll is mirrored in the GAC, so I was able to copy it from there.
Inside EnvSettings.dll is an [assembly: PreApplicationStartMethod] attribute that runs a method in EnvSettings.dll which copiesthe APPSETTING_ and database connection-string settings from Environment Variables into the .NET Framework ConfigurationManager.AppSettings and ConfigurationManager.ConnectionStrings collections.
Note this copying only happens once (during application startup), and only in the first AppDomain - so if you have other AppDomain instances in your application they won't see the updated ConfigurationManager.
Therefore, if you see that your Azure Portal configuration settings for your App Service are not being used when you dump your ConfigurationManager, then the following is likely happening:
You used <clear /> in your <compilation><assemblies> element, which stops EnvSettings.dll from being loaded at all.
In which case you need to either add back the <add assembly="EnvSettings... element from above to your own web.config, or find some other way to load it.
I don't recommend saving EnvSettings.dll locally and adding an assembly reference to your project, as EnvSettings.dll is part of the Microsoft Web Hosting Framework.
Or you have code that is clearing or resetting ConfigurationManager after EnvSettings populates it for you.
Or something else is going on that I have no idea about!
As an alternative to having EnvSettings.dll copy your settings over, another option is to copy the environment-variables over yourself - and as you control the code that does this it means you can call it whenever you need to (e.g. if you ever reset them).
Here's the code I used:
public static class AzureAppSettingsConfigurationLoader
{
public static void Apply()
{
foreach( DictionaryEntry environmentVariable in Environment.GetEnvironmentVariables() )
{
String name = (String)environmentVariable.Key;
String value = (String)environmentVariable.Value;
if( name.StartsWith( "APPSETTING_", StringComparison.OrdinalIgnoreCase ) )
{
String appSettingName = name.Substring( "APPSETTING_".Length );
ConfigurationManager.AppSettings[ appSettingName ] = value;
}
else if( name.StartsWith( "SQLAZURECONNSTR_", StringComparison.OrdinalIgnoreCase ) )
{
String csName = name.Substring( "SQLAZURECONNSTR_".Length );
ConfigurationManager.ConnectionStrings.Add( new ConnectionStringSettings( csName, value, providerName: ""System.Data.SqlClient" ) );
}
}
}
}
See my sample here: http://mvc5appsettings.azurewebsites.net/
// My web.config also has a "HERO_TEXT" key in
// that reads "Value from web.config"
string hero = ConfigurationManager.AppSettings["HERO_TEXT"];
Wiki page on App Settings for .NET:
https://github.com/projectkudu/kudu/wiki/Managing-settings-and-secrets
As already mentioned here, make sure you have that App Setting in the right slot.
As I know, the settings in Azure portal will override existing setting in Web.config. So If you want to ignore the Azure Application settings in portal and use Web.config instead. I am afraid you need to configure the settings in web.config, and remove the same key/pair in Azure portal.

Windows Azure - Migrations is enabled for context 'ApplicationDbContext'

Following this blog with steps by steps http://www.windowsazure.com/en-us/documentation/articles/web-sites-dotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/#setupdevenv
If I run from my local machine then i see the data which is coming from Windows Azure db and i can add and update or delete ... perfectly working fine but the problem is when I publish my application to Windows Azure and I able to see my page and all the static pages are working fine but except one page which is interacting with database.
here is my web.config connection string:
<add name="DefaultConnection" connectionString="server=tcp:* insert server name*.database.windows.net,1433;Database=* insert database name *;User ID=*insert username *#* insert server name*;Password={*insert password here *};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" />
I get this message when i try to access the page from http://XXXX.azurewebsites.net/Employee
Error Message:
Migrations is enabled for context 'ApplicationDbContext' but the database does not exist or contains no mapped tables. Use Migrations to create the database and its tables, for example by running the 'Update-Database' command from the Package Manager Console.
Seems that your database cannot be created automatically. The fastest way to fix that is to follow the suggestion from your error message. Open your Package Manager Console with the project, which contains the connection string and the Configuration.cs (your migrations), selected as the startup project and run Update-Database. It could be that you must pass some parameters to this command if you have changed something on your migrations.

The model backing my context has changed

I have a class library project where my POCO classes live along with a Dbcontext. I am using Code First with data migrations and everything has gone great up to this point. I use the class library in a console application test project and it still works fine there, but I am also trying to use the same exact class library in an MVC project and I get a "The model backing the context has changed since the database was created". Whenever I make a change to the model, I do the database migration update and everything goes well. The model has not still works in the console application just fine.
I have this method in a controller where I am trying to access the context:
public MultiSelectList GetListOfPossibleDispositions()
{
List<DALDevices3.Dispositions> dispositions = new List<Dispositions>();
dispositions = context.Dispositions.GroupBy(d=>d.Description).Select(grp=>grp.First()).ToList();
dispositions.OrderBy(d=>d.Description);
selectListDispositions = new MultiSelectList(dispositions, "id", "Description");
context.Dispose();
return selectListDispositions;
}
Any thought on what might be causing this issue or a possible work around ?
Thanks
In my MVC application I had a connection string name like this:
<add name="DALDevices3.DeviceContextConnectionString" connectionString="Data Source=....
so I removed the connection string since it is code first and still received the same error. I put the connection string back like this:
<add name="DALDevices3.DeviceContext" connectionString="Data Source=....
and the application works. So a connection string is not required in the DAL application, but is needed in the consuming application.

Deployed my Breeze app to Azure Web Sites and Metadata query fails

Just starting off with Breeze and Azure. I downloaded the sample app and added my own controllers. On my local machine it works just fine. When I deploy to my Azure site, I keep getting the following error in the logging section of the page: Query failed: Metadata query failed for: api/CoreData/Metadata; An error has occurred.
I have a controller named Products that simply returns a view. The view contains the js calls to my CoreData ApiController. Follows the sample.
The only thing logged on the server is the following:
At first I was using EF to access data, but have changed to just creating an in-memory object and returning it so as to eliminate db issues.
The URL is http://acapella.azurewebsites.net/products. I've spent quite a bit of time trying to diagnose and research, but feel that I'm overlooking something simple.
Any help or suggestions would be appreciated.
An Azure web site is a free, relatively easy way to deploy a Breeze application where you can test it on a variety of mobile devices and experience your app's responsiveness (or lack thereof).
I have had good success pushing a Breeze app to an Azure web site but there were many stumbles including some that looked like yours.
Two thoughts. First, you'll want to turn "Custom errors off" in your Web.config.
<configuration>
<system.web>
<customErrors mode="Off"/>
</system.web>
</configuration>
My second recommendation: take a look at John Papa's post on deploying an MVC Web API app to an Azure web site. It is excellent. And I know it works.
I hope to have a video on the process very soon.
The first thing you can do is return the exception. In your Breeze controller do this:
[HttpGet]
public string Metadata()
{
try
{
return _contextProvider.Metadata();
}
catch (Exception e)
{
return e.Message + Environment.NewLine + Environment.NewLine + e.StackTrace;
}
}
That made it clear to me something was wrong with my connection string. The exception I got was:
Format of the initialization string does not conform to specification starting at index 0.
My connection string locally seemed ok, but the problem was on Azure. My web.release.config had a correct transform, but when publishing, Visual Studio would add another connection string. You can check this by connecting with FTP to your Azure site and looking at your web.config. I fixed it by selecting the correct connection string when publishing:
After that, there still seem to be two connection strings in my uploaded web.config, but at least it works.

entity Framework 5 changing providers at runtime

I have an application that runs at several client sites. I have to support different DBMS at the locations (SQL Server, DB2, Oracle). I am converting the application from VC++ 6.0 with an ODBC based data layer to Visual Studio 2012 and would like to use Entity Framework (database first). I am having troubles changing the database provider at runtime in my sample application. I changed the connect string in the app.config from a SQL Server to DB2 connect string and changed the default connection factory. Now when I run the program I can connect to the database (at least there is no error) but when I iterate over the linq results I get the exception:
Unable to cast object of type 'IBM.Data.DB2.DB2Connection' to type 'System.Data.SqlClient.SqlConnection'
Here is the program code:
private void btnList_Click(object sender, EventArgs e)
{
using (var ListBill = new LB402_TestEntities())
{
var queryGroups = from Groups in ListBill.LB_Group
select Groups.GroupName;
foreach (string name in queryGroups)
{
lbGroups.Items.Add(name);
}
}
}
The modifed portions of the app.config are:
<defaultConnectionFactory type="IBM.Data.DB2.Entity.DB2ConnectionFactory, EntityFramework" />
<add name="LB402_TestEntities" connectionString="metadata=res://*/LB402.csdl|res://*/LB402.ssdl|res://*/LB402.msl;provider=IBM.Data.DB2;provider connection string="Server=db210:50000;Database=LISTBILL;uid=uuuuu;pwd=ppppp;"" providerName="System.Data.EntityClient" />
From my searching and reading it seems like I should be able to do this, but I am obviously missing something.
Changing connection string is not enough. EDMX file consist of three part and one is provider specific (that is the .ssdl reference from connection string). You need to have this part for every database you need to support and you need to have EF provider for every such database. The problem is that EDMX designer does not support modelling for multiple providers. So you must either have separate EDMX for every database = huge duplicity or you must start maintaining SSDL files for other databases manually (it is XML).
You should make some small Proof-of-concept with code first mapping and DbContext API because it doesn't have these obstacles - SSDL is generated at runtime from code mapping and provider specified in connection string.

Resources