I have gone through the steps to publish my web app using database first on the azure portal.
However, when I publish I get this error message:
Code generated using the T4 templates for Database First and Model
First development may not work correctly if used in Code First mode.
To continue using Database First or Model First ensure that the Entity
Framework connection string is specified in the config file of
executing application. To use these classes, that were generated from
Database First or Model First, with Code First add any additional
configuration using attributes or the DbModelBuilder API and then
remove the code that throws this exception.
My connection string in the web.config after it has been modified by publish:
<add name="MySiteEntities" connectionString="metadata=res://*/MySite.csdl|res://*/MySite.ssdl|res://*/MySite.msl;provider=System.Data.SqlClient;provider connection string="data source=tcp:**********.database.windows.net,****;initial catalog=MySite;user id=username#**********;password=*******;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
My context (generated by edmx):
public partial class MySiteEntities : DbContext
{
public MySiteEntities()
: base("name=MySiteEntities")
{
}
...
I am very confused becuase it seems like entity framework is trying to use code first rather than database first.
UPDATE:
I just tried using the same connection string locally and the web app seems to run fine. The web app does connect to the remote database fine. It is only when I publish to azure it fails.
Read my answer to a similar question at Entity framework work locally but not on azure.
If you made the same "mistake" I did, this is what's happening ... the Azure-deployed app isn't finding your connection string "MySiteEntities" inside your web.config. Instead, at the time your created your Azure Web Site (or Cloud Service or whatever), you created an associated Azure SQL Database and gave its connection string the exact same name, "MySiteEntities". This latter connection string is a "plain" connection string without Model/Database-first metadata references, and so is being treated as a Code-First connection by EF, which then complains about the conflict. See Code First vs. Database First for an explanation of this distinction.
It should be:
<connectionStrings>
<add name="MyDatabaseModelEntities"
connectionString="metadata=res://*/MyDBModel.csdl|res://*/MyDBModel.ssdl|res://*/MyDBModel.msl;
provider=System.Data.SqlClient;
provider connection string="
Data Source=<provideServerName>.database.windows.net;
Initial Catalog=MyDatabase;
Integrated Security=False;
User ID=<provideUserID>;
Password=providePassword>;
MultipleActiveResultSets=True;
Encrypt=True;
TrustServerCertificate=False""
providerName="System.Data.EntityClient"/>
</connectionStrings>
I changed connection string to remote (Azure) on my local web.config, then remove all set connection strings during publishing and publish web.config. It rewrites remove web.config. Then return connection string on local web.config to local connection. It works fine now.
Related
I'm developing an ASP.NET Core 3 Web API with a database first generated db context.
I have the connection string in the appsettings.json file.
Everything is fine when I run it locally on IIS Express.
The problem is that when I publish it on Azure, it gives me the error:
System.ArgumentException: Keyword not supported: 'data source'.
[...]
I noticed that the connection string, when published changed from:
metadata=res://*/DTOs.csdl|res://*/DTOs.ssdl|res://*/DTOs.msl;provider=System.Data.SqlClient;provider connection string='data source=*****;initial catalog=*****;persist security info=True;user id=*****;password=*****;MultipleActiveResultSets=True;App=EntityFramework'",
to:
metadata=res://*/DTOs.csdl|res://*/DTOs.ssdl|res://*/DTOs.msl;provider=System.Data.SqlClient;provider connection string="data source=*****;initial catalog=*****;persist security info=True;user id=*****;password=*****;MultipleActiveResultSets=True;App=EntityFramework""
As a work around I changed the line
services.AddScoped<palmdtos>(_ => new MyDbContext(Configuration.GetConnectionString("myConnectionString")));
to
services.AddScoped<palmdtos>(_ => new MyDbContext(Configuration.GetConnectionString("myConnectionString").Replace(""","'").Replace("&", "&")));
Is there a better way to do it?
Models created with the EF Designer are different from Code First in that your model already exists and is not generated from code when the application runs. The model typically exists as an EDMX file in your project.
The designer will add an EF connection string to your app.config or web.config file. This connection string is special in that it contains information about how to find the information in your EDMX file.
Refer to this article.
The cause was the connection string for one of the EDMX files we were using. Since the EDMX has to be read-only, we had to use a different connection string in Azure.
When replacing "e; by a single quote ', it will work fine again. So go to azure website > Configuration > Connection strings > add your conn string with custom type.
Note: Make sure you also select Custom instead of SQLAzure for your Entity Framework connection string, even though the database runs on Azure.
Can you try updating the settings?
In Azure Panel:
Select App -> Application Settings -> Enter new Connection String -> Save
I am going to try and explain this issue as clear as I can.
I start with two projects:
Project One: Data model
A repository class that wraps a DbContext that has a single DbSet: RentalListings
This DbContext uses the default settings, so that when I save changes it saves to local DB.
Project Two: Console App
Contains a console application that when runs, instantiates an instance of the repository class.
Then it creates multiple "RentalListings" and saves them to the repository.
So far so good. After running the console app I check the local DB SQL object explorer, and my repository class has successfuly saved to this db.
Now, I want a way to access this inserted data via a Web API. So I add:
Project Three: Web API
I create a new controller class and add a single GET action method to fetch all listings.
When I run the API project, I can hit the action method, which looks like:
[HttpGet]
public IEnumerable<RentalListing> GetAllListings() {
StatsRepository repository = new StatsRepository(new StatsContext());
return repository.GetRentalListings();
}
via the correct URL. However I am getting the following error returned:
Unable to complete operation. The supplied SqlConnection does not specify an initial catalog or AttachDBFileName.
Now, from searching the web I think the issue is that it doesn't know how to access the database??? And that I should specify a connection string in the Web.config file in my Web API project.
Questions:
1) How did my console app, that doesn't specify a connection string, create a mdf database using my repository class?
2) Why doesn't the same work for my web api project? can't it just use the repository to fetch the database, just like the console app did?
Look forward to hearing the replies, thanks in advance!
Q :1. How did my console app, that doesn't specify a connection string, create a mdf database using my repository class ?
A :1. It is by default.If you didn't specify the connection string on console app then it uses your context class namespace plus name of the context class to create a db.
e.g.
Context class namespace = MyDbContextNameSpace
Name of the context class = MyContext
Then your DB name will be like this : MyDbContextNameSpace.MyContext.
Note : If SQL Express is installed then the database is created on your local SQL Express instance (.\SQLEXPRESS). If SQL Express is not installed then Code First will try and use LocalDb ((localdb)\v11.0).
You can read more about it here : Building an Initial Model & Database
Q :2. Why doesn't the same work for my web api project? can't it just use the repository to fetch the database, just like the console app did?
A :2. When you talk to EF through Http/s,you have to provide the connection string on web.config file. Otherwise EF doesn't know how to do that.That is by design.
e.g.
MyContext.cs
public class MyContext : DbContext
{
public MyContext() : base(“name=MyContextConn”)
{
}
public DbSet<Blog> Blogs { get; set; }
}
web.config
<connectionStrings>
<add name=“MyContextConn“ connectionString=“conndetails”
providerName=“System.Data.SqlClient“ />
</connectionStrings>
The DbContext class can definitely be responsible for 'specifying a connection string', as you put it, but the reason it is most commonly found in a config file is so that different connection strings can be specified for different configurations. For example, your Web.Debug.config connection string might point to an instance of SqlExpress that you have installed on your development box and the Web.Release.config connection string might point to a Sql instance contained in Azure.
Specifying a connection string in your config file isn't necessarily going to fix the issue. The connection string can specify a username and a password. If you put those in to the connection string then it will most likely work. For example <add name="DefaultConnection" connectionString="Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;" providerName="System.Data.SqlClient" />
The issue you are experiencing is most likely due to the fact that the console application is running under the context of the Windows user launching the application. It is using those credentials to connect to the database. I'm assuming that your console, webapi app and sql are all installed/running on the same machine and that your user is the only one that you use to log in to sql(again assuming you are using SSMS). The web application though is most likely being run through IIS or IISExpress which is run under a different context by default(I believe IUSR for IIS). If you would like to have your connection string use integrated security(to keep your username and password out of your configs -- which is generally considered a good practice) like this: <add name="DefaultConnection" connectionString="Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=True" providerName="System.Data.SqlClient" /> then you would want to setup the context that the application is being run under by updating the user the apppool is running under. You would do this by updating the app pool identity and then making sure that the web application is using that app pool.
Hope this helps.
Everything works great when I run my project locally, but when I deploy to Azure I get the following error.
"Code generated using the T4 templates for Database First and Model First development may not work correctly if used in Code First mode. To continue using Database First or Model First ensure that the Entity Framework connection string is specified in the config file of executing application. To use these classes, that were generated from Database First or Model First, with Code First add any additional configuration using attributes or the DbModelBuilder API and then remove the code that throws this exception."
My connection string is:
add name="LifeEntities" connectionString="Server=tcp:abc000000ab.database.windows.net,1433;Database=Life;User ID=myid#abc000000ab;Password=mypw;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" providerName="System.Data.SqlClient"
I'm getting this error when my code tries to open the context of my entity framework database. Note, that I'm using a pretty basic MVC project template that does ASP.NET Identity as well.
I've read that this is because of code first vs data but not sure how to solve this issue.
That's a pure SQL connection string. You need to use a EF connection string, including the model metadata etc.
Here's an example:
<add name="Context" connectionString="metadata=res://*/Context.csdl|res://*/Context.ssdl|res://*/Context.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=Context;integrated security=True;MultipleActiveResultSets=True;"" providerName="System.Data.EntityClient" />
After I deployed my mobile service to Azure, calls to the service fails because of this error:
No connection string named 'ApplicationEntities' could be found in the application config file.
The error only occurs on Azure side. When I test the service locally, the connection to the remote database works without a problem.
I separated my solution into several projects:
Web Api
Business Logic
Data Access (contains the DbContext, database first)
Common (contains the entities generated by EF)
As I always do, I copied the connection string generated in my app.config of the DataAccess Assembly into the connectionStrings-Element of my web.config (Web Api project).
<connectionStrings>
<add name="ApplicationEntities" connectionString="<the connection string>" providerName="System.Data.EntityClient" />
</connectionStrings>
In the web deploy settings, I selected the connection string for "ApplicationEntities". I tested it with and without the option "Use this connection string at runtime (update destination web.config). I always get the same error.
Then I got curious and logged the connection strings available via the ConfigurationManager with something like this:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ConfigurationManager.ConnectionStrings.Count; i++)
{
sb.AppendLine(ConfigurationManager.ConnectionStrings[i].ConnectionString);
}
trace.Info(sb.ToString());
I got two connection strings:
data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true
Data Source=theserver.database.windows.net;Initial Catalog=thedb_db;User ID=theuser;Password=thepassword;Asynchronous Processing=True;TrustServerCertificate=False;
The username and password is strangely different from the username and password stated in the management portal.
Also the EF-Metadata information get lost.
I get this connection strings when testing locally:
data source=.\\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true
metadata=res://*/DataContext.ApplicationEntities.csdl|res://*/DataContext.ApplicationEntities.ssdl|res://*/DataContext.ApplicationEntities.msl;provider=System.Data.SqlClient;provider connection string=\"data source=theserveraddress,1433;initial catalog=thedb_db;persist security info=True;user id=theusername;password=thepassword;MultipleActiveResultSets=True;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;App=EntityFramework\"
I expect to get the same connection strings when running on Azure. Any idea what's going wrong?
Update:
I just went for remote debugging the service (see here). As I opened the downloaded publish-profile in my text editor, I discovered that there is an attribute SQLServerDBConnectionString - containing the connection string that always gets forced when deployed - with the same username and password I'm not aware of that it exists.
I tried to overrwite this connection string but it did not help. That connection remains the active.
Update 2 / May 29th 2014:
Seems that in the meantime the error has been fixed by the azure mobile team. Still running the same code using the database first approach and it's working now. Thanks a lot!
I have myself tried using DB first approach with dot net backend mobile services & ran into same sort of problems as you. Digging around further, following is my observation :
The azure mobile service with dot net backend must use code first approach only. This generates a specialised connection string with metadata (starting with res:)
The name of the connection string has to be the same as it is when you download the default sample todo app I.e. Ms_TableConnectionString.
There is an option in azure websites to select custom SQL provider to help make a custom connection string, this option, however, is not available for dot net backend mobile service in Azure Management portal.
P.s. Posting as answer because I don't have a enough points to comment..
Just wanted to give an update that I have been looking at this for some time and think I for the first time see it too. I don't know what is going on but wanted to let you know that we are indeed looking at it.
Henrik
(I don't have enough points to comment so having to do this as an answer)
Henrik, I have this same problem. If I ftp on to the box I can see that the web.config has the correct connection string but it fails as trying to use the username in the SQLServerDBConnectionString property (OoWUqr****Login). Is it possible you could let me know in what order it is looking for connection strings and where?
And if it can't stop it using the other user is there a way I can permission them for the correct database through mobile services?
Thanks
F
Quick Background
I received code from a third party (contracted software) that I have to move onto my servers. When I run the code using their connections and service references, everything works well. When I debug locally, everything works well. My problem only occurs when I try to run the application/service(s) after I move them onto my server.
The services (or their respective references) are at the heart of what's causing the issues. I created a test client to try to debug the services, and it's accessing the service, but erroring when it tries to connect to the SQL Server inside the service. The code appears to use the Entity Framework which I am admittedly not familiar with yet.
Errors/Issues
When I use my test client to call a function inside the service reference, it errors out when it tries to connect to my SQL database:
using (ApplicationDefinitionDBEntities appDefDb = new ApplicationDefinitionDBEntities()) //ERROR
Here's the error I receive (domain and server names have been made generic):
System.Data.SqlClient.SqlException (0x80131904): Login failed for user 'MYDOMAIN\APPSERVERNAME$'.
I found the app.config that is referenced by the .edmx file (ApplicationDefinitionDB.edmx) and its accompanying files. Here is the connection string (made generic):
<add name="ApplicationDefinitionDBEntities"
connectionString="metadata=res://*/Data.ApplicationDefinitionDB.csdl|res://*/Data.ApplicationDefinitionDB.ssdl|res://*/Data.ApplicationDefinitionDB.msl;
provider=System.Data.SqlClient;
provider connection string="data source=MYDBSERVERNAME;initial catalog=myDBcatalog;
User ID=myUserID;Password=myPassword;integrated security=false;
multipleactiveresultsets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
There is also an old connection string that the third party used which had integrated security set to true and reference SQLExpress, but I commented it out.
Note that I am specifying integrated security to be false (I know it's by default but I wanted to be explicit), and also supplying a username and password to the SQL Server. So why is the error message in the service ref test client saying that it's trying to connect using DOMAIN\APPSERVER$ as though it's using integrated security?
I am using IIS to host my app and SQL Server for database work. I think I have updated and re-generated all Entity Framework stuff for the database reference, but I could be missing something. Can anyone suggest anything that I may be missing to make sure the service reference uses the connection string supplied in it, and NOT the app server domain login? Thanks!
Turns out that connection string conflicted with one above the project level of the service. The project that housed the service uses Silverlight, so I thought the ClientConfig files were the only other configs being used, but there was another one hiding in the project that I published. When I rooted around in that web.config file, I found that there was a connection string with Integrated Security turned on. Once I turned that off it worked fine. That's annoying.