Code-first MVC 4 using Entity Framework and SQL Server 2012 - sql-server

This question is not about SQL Server "3xpr355" (the obfuscation
in quotes is by design; it should prevent future searches from hitting
dead-ends, as mine have done).
I am using code-first and Entity Framework to develop an MVC 4 application. The SQL Server, IIS, and Visual Studio are all running on the same machine.
I was originally using SQL Server "3xpr355" but the requirement to put it on an exposed-to-the-Internet-via-ISS machine made hooking it up to a full-featured SQL Server necessary. I have the application set up to drop and re-create the database whenever the models change:
public class XyzDBContext : DbContext
{
public XyzDBContext()
: base("XyzDBContext")
{
Database.SetInitializer<XyzDBContext>(new DropCreateDatabaseIfModelChanges<XyzDBContext>());
}
public DbSet<XyzModel> XyzModels{ get; set; }
}
Here are my connection strings:
<connectionStrings>
<add
name="DefaultConnection"
connectionString="Data Source=.;Initial Catalog=aspnet-Xyz-20150131102119;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
<add
name="XyzDBContext"
connectionString="Data Source=.;Initial Catalog=XyzDatabase;Integrated Security=True"
providerName="System.Data.SqlClient"/>
</connectionStrings>
Expectations:
Execution of the portions of the application that use XyzDBContext should cause the database "XyzDatabase" to be created (if necessary).
Execution of the portions of the application that use the Membership Provider should cause the database "aspnet-Xyz-20150131102119" to be created (if necessary).
Actual Results:
Exception is thrown: System.Data.ProviderIncompatibleException "An
error occurred while getting provider information from the database.
This can be caused by Entity Framework using an incorrect connection
string. Check the inner exceptions for details and ensure that the
connection string is correct."
Inner Exception:
System.Data.ProviderIncompatibleException "The provider did not
return a ProviderManifestToken string."
Inner Exception:
System.Data.SqlClient.SqlException "Login failed for user
'DOMAIN\SERVER$'."
Measures:
I have tried using SQL Server Management Studio to add a login for the "DOMAIN\SERVER$" user, but the login always fails.
I have researched and tried many permutations of the connection strings, all but a few of the examples I have found were for use with SQL Server "3xpr355".

Well if you map each connection string (database) to it's own DbContext the you could reach your expectations but you still have to work with two contexts (which is painful).
Your third actual result is due to IIS that can't connect to the database. You have to go to IIS manager and change the identity of the application pool under which your application runs (You can change it to LocalSystem)
Finally, try this if you have already the databases created:
public class DefaultConnectionContext : DbContext, IDisposable
{
public DefaultConnectionContext()
: base("name=DefaultConnection")
{
Database.SetInitializer<DefaultConnectionContext>(null);
}
// Some dbsets
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
public class XyzDBContext : DbContext, IDisposable
{
public XyzDBContext()
: base("name=XyzDBContext")
{
Database.SetInitializer<XyzDBContext>(null);
}
// Some dbsets
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Hope That helps

The solution to this problem is multifaceted:
Create an Application Pool
In IIS Manager, visit the "Application Pools" node and select the "Add Application Pool..." Action:
Select the new Application Pool and select the "Advanced Settings..." Action, then select the "..." button (on the "Identity" field):
Set the Application Pool identity to "LocalSystem"
Grant Permission
In SQL Server Management Studio (when connected to the database service), visit the "NT AUTHORITY\SYSTEM" node under "Logins" and bring up the "Properties" view, then select the "Server Roles" page, and grant all of the privileges by selecting the check-boxes:
In IIS Manager, Right-click on your site and select "Manage Application/Advanced Settings..." and Set the "Application Pool" property value to "CodeFirstMVC".
Run the Application
Run the application and visit the areas that would require a new database to be created; you should now see a new database on your SQL Server instance.

Related

Specified username in connection string gets replaced at runtime

I have a web site project as an entry point and defined the connection string there:
"ConnectionStrings": {
"DataPlaygroundConnection": "Server=DataPlayhouse;Database=BusinessHandshake;User ID=bhuser1;Password=bh#12345;MultipleActiveResultSets=True;Connect Timeout=360;App=Company - Portal - Staging"
}
I started facing issues just recently that when running, I'd get Login failed for user 'bhuser1' error. But the credentials are working as I can connect to DB with any DB Manager (SSMS). Then I added Serilog to understand whats happening as the exception was thrown from Program.cs
After adding Serilog, I find this exception block:
10/20/2020 07:54:49 +04:00 Application Starting.
10/20/2020 07:54:49 +04:00 Using an in-memory repository. Keys will not be persisted to storage.
10/20/2020 07:54:49 +04:00 Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.
10/20/2020 07:54:49 +04:00 No XML encryptor configured. Key {a012bed6-42e0-475d-a11d-44ae3a5599a9} may be persisted to storage in unencrypted form.
10/20/2020 07:54:58 +04:00 An error occurred using the connection to database '"BusinessHandshake"' on server '"DataPlayhouse"'.
10/20/2020 07:54:58 +04:00 An exception occurred while iterating over the results of a query for context type '"Folio.Infrastructure.Data.Contexts.PlaygroundBiContext"'."
""Microsoft.Data.SqlClient.SqlException (0x80131904): Login failed for user 'bhuser1'.
The credentials in the json file are correct and I am able to use the same credentials in Azure Studio to connect to the database.
I do not have any customization code in context:
public partial class PlayHouseContext : DbContext
{
public PlayHouseContext()
{
}
public PlayHouseContext(DbContextOptions<PlayHouseContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("");
}
}
}
I have a similar error on my local dev machine: SqlException: Login failed for user 'bhuser1'.
On my dev machine, the credentials are correct and I can use SSMS to easily access the said DB and all the elements within.
I'm unable to understand this one.
Thanks #DaleK.
Trusted_Connection means windows authentication. I had to remove that and do the same in the appsettings.Development.json as well.

Entity Framework code first causes exception on database access

Recently started trying to dig into code first approach for Entity Framework. I have crated some database tables following various tutorials but none of them did the trick.
Starting from scratch about 3 to 4 times now because the exceptions get more and more absurd. Last time created the database on first access but wasn't able to connect to the database in a second debug session because of missing permissions (using integrated security - wat?). Apparently the .mdf was blocked by System process and only a restart in safe mode allowed me to get rid of it.
Anyway, anew. I have a class library, which contains the database models and a gateway class for external access. I have a Console project to test the database creation and access. EF is installed in the class library via NuGet, reference to EntityFramework.SqlServer.dll is added to the Console project.
The connection string looks like this in both projects:
<connectionStrings>
<add name="DbConnection"
connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\LanguageCreator.mdf;Initial Catalog=LanguageCreator;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
My context class looks like this:
public class LanguageContext : DbContext {
public LanguageContext() : base("DbConnection") {
// Have to set the DataDirectory in code because the wrong one gets set from the config.
AppDomain.CurrentDomain.SetData("DataDirectory", Directory.GetCurrentDirectory());
Database.SetInitializer(new CreateDatabaseIfNotExists<LanguageContext>());
public DbSet<Language> Languages { get; set; }
public DbSet< ... blablabla various other DbSets following, nothing of interest here.
}
This is what my gateway looks like:
public class Gateway {
public void InitializeDatabase() {
using (LanguageContext context = new LanguageContext()) {
context.Database.Initialize(true);
// I did have a configuration class for migration, which seeds some initial data, which is why I'm trying to read the WordTypes here but I left that thing out this time ... will try to add it later on.
IEnumerable<WordType> wordTypes = context.WordTypes.AsEnumerable();
List<Language> languages = context.Languages.ToList();
}
}
}
The call simply looks like this:
class Program {
static void Main(string[] args) {
Gateway databaseGateway = new Gateway();
databaseGateway.InitializeDatabase();
}
}
Now, without absolutely anything special, I recieve the following error on starting a debug session:
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. Cannot create an automatic instance. See the Windows Application event log for error details.
Unfortunately, the Windows Application event log doesn't show any details to that error. Or maybe I'm too stupid to find it ...
What is actually causing this issue and how can I fix this? Everything I found was about access to external SQL Servers but I simply want EF to create an .mdf locally and connect to that.
I'm very new to Entity Framework and databases in general, but I have a couple suggestions that may help narrow down the issue.
"Verify that the instance name is correct and that SQL Server is configured to allow remote connections." See if the problem is with the server by connecting to it with a different program. If you have trouble connecting to it outside of EF, you can eliminate EF as the problem.
If you can, leave out the connection-string or any mention of your SQL database and see if EF will generate a LocalDB for you. I believe this is the default behaviour of EF. If this works, I think this would also suggest that there's something about your SQL server that's giving you trouble.
Again, I'm very new to this, so just thoughts I'd suggest the way I would try to problem-solve this with my limited knowledge. Hope it's helpful!
Okay, I figured it out on accident. I installed EntityFramework via NuGet in the Console project and voilá, Visual Studio created the .mdf on starting a debug session.
As it still worked after uninstallation of EntityFramework I created the project anew and checked for differences. I found out that the EntityFramework entries in the app.config were still present, so I copied them over to the new project and now that worked as well.
So if you're stuck with the same problem try adding these parts in the app.config of your console project (or whatever project type you use to access your database class library):
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</configSections>
<connectionStrings>
<add name="LanguageCreator.data.LanguageCreatorContext"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MyContext.mdf;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>

Can't access SQL Server via IIS

I want to run my ASP.NET MVC application on the local IIS 8 server but I can't get access to SQL Server 2014. Both IIS and SQL Server run on the same host and I am using Windows 8. This is what I have done so far:
In the application I created a model called Employee:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
I want to connect to the database with using Entity Framework so I created another class called EmployeeDbContext:
public class EmployeeDbContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}
I have only one Home controller:
public string Index()
{
EmployeeDbContext employeeDbContext = new EmployeeDbContext();
return "Hello world";
}
I am using SQL Server 2014 Express engine with Windows Authentication and the name of my computer is ZSÓTÉ. Here is the connection string from the web.config:
<add name="EmployeeDbContext"
connectionString="Server=ZSÓTÉ\SQLEXPRESS;Initial Catalog=Test;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
In the Global.asax I didn't set any initializer strategy so by default if the Test database doesn't exist, then the application should create it automatically.
After that I set on the properties window to use IIS Local Server and I create a virtual directory for the application. So far everything is ok, I can see the application in the IIS manager and I set to run under the DefaultAppPool. After that I set all the permissions of the project folder for the IIS APPPOOL\DefaultAppPool object. The settings are fine I can access the application from the IIS server perfectly.
Finally I created a login for IIS APPPOOL\DefaultAppPool in SQL Server Management Studio and I set these two roles: public and dbcreator. But even after all these setups the application doesn't work correctly via IIS.
Though I get the "Hello world" message on the browser, but the Test database is never created. The strangest thing is if I make some malicious change in the connection string, I don't even get any compilation error, just the "Hello world" message in the browser.
What am I doing wrong? Thank you in advance!
The database is created the first time you access to entities.
Try to do this:
public string Index()
{
EmployeeDbContext employeeDbContext = new EmployeeDbContext();
employeeDbContext.Employees.ToList();
return "Hello world";
}
At this point you will receive an error if db creation does not work.
Next steps if something still does not work:
In the connection string use .\SQLEXPRESS because could happen everything to accents.
Assign to the user in SQL Server system administration role. If it work you then start to reduce rights (or, better, change approach).

ELMAH for ASP.NET MVC 4 using SQL SERVER 2008 R2

I ran ELMAH sql scripts in test DB(It created ELmah_Error table and 3 stored procedures) and configured ELMAH in MVC application using Nuget.
I modified web.config as specified and I'm able to log exceptions into
http://mysite/elmah.axd
But, instead i want to log the exceptions into Sql Server.
I added below class to achieve that
public class ElmahHandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
public override void OnException(System.Web.Mvc.ExceptionContext context)
{
LogException(e);
}
private static void LogException(Exception e)
{
// Call to Database and insert the exception info
}
}
Final step was to:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ElmahHandleErrorAttribute ());
}
Is it the correct way to use ELMAH to log all exceptions or AM I missing something?
Once you have the database setup, all you need to do is add the following to the <elmah> section your web.config to setup the Elmah to log to the SQL Database:
<elmah>
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="<DBConnString>"
applicationName="<YourApp>"
</elmah>
Replace <DBConnString> and <YourApp> with appropriate values for your configuration.
Once you have done this you will not need to use your custom ElmahHandleErrorAttribute class.
I am not sure which NuGet package you installed, but I would recommend using the Elmah.MVC package as it integrates Elmah into MVC exceptionally well by setting up all of the ErrorHandlers and ErrorFilters for you.

asp mvc 3 noobie: CREATE DATABASE permission denied in database 'master'

I'm an asp mvc 3 noobie. I've done a few tutorials and am now ready to keep learning by trying to build a site.
In all the tutorials, you connect to a SQL CE or SQL Express DB. But I want my site to build a DB on sql server.
I created a database on my networked server that I'll call MyDB. Then I set my connection string in my web config file like this:
add name="ApplicationServices"
connectionString="Data Source=Server\ServerInstance;Initial Catalog=MyDB;Integrated Security=True"
providerName="System.Data.SqlClient"
I created models and a scaffolding controller.
I created a simple DataBaseContext like this:
Imports System.Data.Entity
Public Class DatabaseContext
Inherits DbContext
Public Property Employee As DbSet(Of Employee)
Public Property AnnualLeave As DbSet(Of AnnualLeave)
End Class
But when I hit the following line in the scaffolding controller, i get the error:
Function Index() As ViewResult
Return View(db.Employee.ToList()) //CREATE DATABASE permission denied in database 'master'`.
End Function
Should I fix this by changing the permissions on the MyDB database? Is this a permissions issue on the SQL server side? I am confused why I am getting a Create database error because the DB already exists.
Am I getting this error b/c I have already created the database? Does the scaffolding want to create the database somehow?
Sounds like it is trying to create a new DB by the error message. I'm guessing that you are using EF code first with your project and using it's migration capability to build your DB. Check the setup of the EF context to make sure it's using your connection string.
The connection string or its name can be passed to constructor of DbContext. If you are using default constructor it searches for the connection string with the same name as the name of your derived context class. Basically, make sure your connection string has the same name as your derived dbcontext class and it should find it.
See this post for additional information
1.You need to set IIS app pool identity to be ASP.NET integration mode.
2.Add a login in SQL Server for IIS APPPOOL\ASP.NET.
3.In SQL Server, set IIS APP POOL login to have dbcreator role.
USE master;
EXECUTE sp_addsrvrolemember #loginame = N'YourAppUserLogin', #rolename = N'dbcreator';
<add name="Default" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=test2;user id=sa;password=123456"
providerName="System.Data.SqlClient" />
Use this connection string for your application

Resources