Why my identity database table is not migrated to Azure? - c#

When publishing my first ASP.NET Core 2.1 web app in Azure from Visual Studio 2017, I am setting up EF migrations like in the picture below:
After running Publish, the identity table is not created. In Configure -> Settings I have info, that No databases found in the project.
Also I am using console command:
dotnet ef database update --context AppIdentityDbContext
What gives me same result. Connection strings I am taking from Azure Show database connection strings, updateting them with username and password.
I am not sure what I am doing wrong here. Everything works perfectly on my computer. I will be thankful for any suggestions to check.
Right now, after trying to populate Identity table:
public static class IdentitySeedData
{
private const string adminUser = "****";
private const string adminPassword = "****";
public static async Task EnsurePopulated(UserManager<IdentityUser> userManager)
{
IdentityUser user = await userManager.FindByIdAsync(adminUser);
if (user == null)
{
user = new IdentityUser("Admin");
await userManager.CreateAsync(user, adminPassword);
}
}
}
I am getting error:
AggregateException: One or more errors occurred. (Invalid object name 'AspNetUsers'.)
System.Threading.Tasks.Task.ThrowIfExceptional(bool includeTaskCanceledExceptions)
SqlException: Invalid object name 'AspNetUsers'.
System.Data.SqlClient.SqlCommand+<>c.<ExecuteDbDataReaderAsync>b__108_0(Task<SqlDataReader> result)
UPDATE: I found out, that my problem occurs only identity database.

As I did not managed to migrate my Identity database to Azure, I found alternative solution here: Invalid object name 'dbo.AspNetUsers' in Asp.NET MVC 5 Entity Framework

Related

Entity Framework Core automatically inserts double quotes in Oracle database

I'm developing an ASP.NET Core 6 MVC web app, and I want to use the integrated Identity platform to handle user roles and authentication.
Since this web app must be cross-database, I need to make this work on a Oracle autonomous database. So I've installed the Oracle.EntityFrameworkCore package from NuGet, and switched to the UseOracle method in the ConfigureServices method of my Startup.cs file.
services.AddDbContext<ApplicationDBContext>(options =>
{
// options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
options.UseOracle(Configuration.GetConnectionString("OracleConnection"))
});
The connection can be established, but here's the issue: when prepping up the UserManager and creating User Roles in Startup.cs, any standard method that EF Core invokes actually executes a query with double quotes around object names, e.g. doing this
private async Task CreateRoles(IServiceProvider serviceProvider)
{
//Custom roles
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
string[] roleNames = { "Admin" };
IdentityResult roleResult;
foreach (var roleName in roleNames)
{
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (!roleExist)
{
// create the roles and seed them to the database: Question 1
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
await CreateUser(serviceProvider, "Admin");
}
This code executes this query:
SELECT "a"."Id", "a"."ConcurrencyStamp", "a"."Name", "a"."NormalizedName"
FROM "AspNetRoles" "a"
WHERE "a"."NormalizedName" = :normalizedName_0
FETCH FIRST 1 ROWS ONLY
which fails.
It searches for an "AspNetRoles" table, double quotes means it searches EXACTLY that, and thus it doesn't exist because tables are all uppercase in Oracle autonomous database, and cannot be CamelCase. I get an error ORA-00942.
I can't figure out how to make EF Core NOT use double quotes without reverting to the DevArt Oracle package.
How can I solve this?
In the end I understood the problem wasn't only for Identity Provider tables.
So I've implemented linq2db and linqToDb.Identity and made it work by putting
OracleTools.DontEscapeLowercaseIdentifiers = false;
in the ConfigureServices method of Startup.cs.
Quick note: LinqToDb.Identity NuGet package is stuck on a May 2021 release which is incompatible with recent Linq2DB packages due to various missing references to this (e.g. this.GetTable) in the IdentityDataConnection class, so you might as well download the source code and include it in your project (or make a class library out of it) and fix the class.
Repo link: https://github.com/linq2db/LinqToDB.Identity

Entity Framework and using a specific database

My Database Team created a database called XMEN.
I need to use that specific database with my project. I have full admin rights on that database but not on the server (they won't give it to me).
CREATE DATABASE permission denied in database 'master'.
When I run my project, I get the error above because I don't have permission to create a database. How can I use entity frameworks to specify which database to use? I want Entity Framework to manage everything else (tables, relationships, etc)
------------- UPDATED 9/17/2020 - 9:12 AM EST
public class XmenContext : DbContext
{
//public XmenContext(DbContextOptions<XmenContext> options)
// : base(options)
//{
//}
public XmenContext() : base("XmenDatabase")
{
}
Now I get an error saying cannot convert from String to Microsoft.EntityFrameworkCore.DbContextOptions
I clicked the link in your answer.
You should add the database name to the connection string in your configuration file.
If you need some help you can view here :
https://learn.microsoft.com/en-us/ef/ef6/fundamentals/configuring/connection-strings
If you are having trouble add your connection string to the question (without sensitive information) and I will try to help.
Good luck !

IdentityServer4 How to register user and manage resources

I am planning to use the IdentityServer4 to handle authentication/authorization for multiple projects (every project will have its own WebAPI). So user maybe have to register once and get a flag or role for which product/api they have access to.
I have already been through the IdentityServer4 docs and started with InMemoryUsers which I now changed to IdentityUser with Entity Framework Core
// Adds Identity - configure identity server
services.AddIdentityServer()
// .AddSigningCredential(key, StoreLocation.LocalMachine, NameType.Thumbprint)
.AddTemporarySigningCredential()
.AddConfigurationStore(builder => builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationsAssembly)))
.AddOperationalStore(builder => builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationsAssembly)))
.AddAspNetIdentity<IdentityUser>();
So I created like in the thread User Registration Process with IdentityServer4 already mentioned, three different projects.
Identity Provider = Asp.Net Identity project (could be company website with user registration)
Identity Server = Asp.Net project containing the identity server middleware
A protected API = Web Api
I also have to mention that I am using Entity Framework Core 1.1.1.
But now the question came out, how to handle the database access from the different projects?
The Identity Provider and the Identity Server are currently using the same database. Both projects have migration enabled, but could that be right?
IdentityProvider with ApplicationDBContext and IdentityServer=OAuthService with ApplicationDBContext, both with Migration enabled
So my first question is, isnĀ“t that a problem to handle two migrations to the same data source? (It seems that in Entity Framework Core, wont be executed automatically -which is good- and migrations have to be executed manually)
Which way is recommended to handle the Clients, API resource, Claims, Scopes, etc. for the IdentityServer4? Shall I create an additional project, which also use the same database just to manage the configuration data?
So I am not sure how to handle database access to one database from different Asp.Net projects with Entity Framework Core.
My database currently looks like that:
IdentityServer database with Asp.Net Identities
The following code will be executed within the Startup.cs of the SocialNet.OAuthService project.
private void InitializeDbTestData(IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.GetService().CreateScope())
{
// create identity server EF structures
serviceScope.ServiceProvider.GetRequiredService().Database.Migrate();
serviceScope.ServiceProvider.GetRequiredService().Database.Migrate();
serviceScope.ServiceProvider.GetRequiredService().Database.Migrate();
var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
// add dummy/example data
if (!context.Clients.Any())
{
foreach (var client in ExampleConfig.GetClients())
context.Clients.Add(client.ToEntity());
context.SaveChanges();
}
if (!context.IdentityResources.Any())
{
foreach (var resource in ExampleConfig.GetIdentityResource())
context.IdentityResources.Add(resource.ToEntity());
context.SaveChanges();
}
if (!context.ApiResources.Any())
{
foreach (var apiResource in ExampleConfig.GetApiResources())
context.ApiResources.Add(apiResource.ToEntity());
context.SaveChanges();
}
var userManager = serviceScope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
if (!userManager.Users.Any())
{
foreach (var testUser in ExampleConfig.GetUsers())
{
var identityUser = new IdentityUser(testUser.Username)
{
Id = testUser.SubjectId,
UserName = testUser.Username,
Email = testUser.Username,
EmailConfirmed = false
};
foreach (var claim in testUser.Claims)
{
identityUser.Claims.Add(new IdentityUserClaim<string>
{
UserId = identityUser.Id,
ClaimType = claim.Type,
ClaimValue = claim.Value
});
}
userManager.CreateAsync(identityUser, "Password123!").Wait();
}
}
}
}
I hope I could describe my problem comprehensible and I hope the formatting is conform to the guidelines.
I am really thankful for your help.
Best Regards Michael

Change ASP.NET Identity to use existing database

I'm using ASP.NET MVC 5 with a Database-First workflow. I've created the Identity tables (AspNetUsers, AspNetRoles etc.) in my existing database however I'm having problems getting the register and login functionality to work properly.
This is the IdentityModels.cs class
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyConnectionString") // I use "MyConnectionString" instead of "DefaultConnection"
{
}
This is what the EF connection string from the web.config looks like
<connectionStrings><add name="MyConnectionString" connectionString="metadata=res://*/Entities.MyModel.csdl|res://*/Entities.MyModel.ssdl|res://*/Entities.MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=My-Pc\SQLEXPRESS;initial catalog=MyExistingDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
And for good measure here's the context class generated from the edmx
public partial class MyConnectionString : DbContext
{
public MyConnectionString()
: base("name=MyConnectionString")
{
}
To me all seems well and it should be able to create users in the database however I'm getting the following error when logging in or trying to register respectively:
For login:
The entity type ApplicationUser is not part of the model for the
current context
Line 73: var result = await SignInManager.PasswordSignInAsync(model.Email,
model.Password, model.RememberMe, shouldLockout: false);
Exception Details: System.InvalidOperationException: The entity type
ApplicationUser is not part of the model for the current context.
For register:
The entity type ApplicationUser is not part of the model for the
current context
Line 155: var result = await UserManager.CreateAsync(user,
model.Password);
Exception Details: System.InvalidOperationException: The entity type
ApplicationUser is not part of the model for the current context.
Most articles around seems to be focusing on Code-First and how to go from LocalDb to SQLExpress etc. and how to change the connection string however I haven't been able to solve this problem for a good amount of time.
Edit, solution: As #ChrFin mentioned you could use them both side by side which is what I ended up doing. I simply added a new regular connection string in web.config and let it point to the existing database. PS. remember that the connection string name cannot be the same as the existing one and must be the same you provide to the ApplicationDbContext constructor.
I THINK this scenario is not supported by ASP.NET Identity as it needs a DbContext which extends IdentityDbContext<ApplicationUser> (or similar).
Why are you forcing Identity into your DB-First context?
You can use a Code-First context for Identity alongside your other DB-First context without problems...
You can resolved this problem by following these steps:
1-create aspnetuser etc tables on your database (whatever DB you want
to use)
simply connect the application with that database not using entity framework, i'm saying just simple connection.
you will find connection string in web.config file.
place this connection string into identity model clsss
your Register and Token methods now running
now you can use entity framewoek for rest of your tables by data first approach

SQL Server CE Code First migrations problems

I have a bunch of problems trying to enable (code-first) migrations for my SQL Server Compact 4.0 database for my desktop .NET app.
Enable-Migrations does work and the directory Migrations is created. After that when I try to run Add-Migration InitialMigration, I get:
Access to the database file is not allowed. [ 1914,File name = Logo.sdf,SeCreateFile ]
This is the first problem, but I solved it by running Visual Studio as Administrator... don't like that solution and also don't know if later in production it will work without the app being run in Admin mode. I let that problem aside for now...
My connection string:
<add name="LogoContext"
connectionString="Data Source=Logo.sdf"
providerName="System.Data.SqlServerCE.4.0"/>`
So after running Add-Migration InitialMigration in Administrator mode I get an empty migration... that's ok. Then I delete the migration and add a new class:
using System;
using System.Collections.Generic;
public class Blog
{
public int ID { get; set; }
public string Title { get; set; }
}
I add a reference to the context class:
public class LogoContext : DbContext
{
public DbSet<Word> Words { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Blog> Blogs { get; set; }
}
Then run Add-Migration InitialMigration again and get:
public partial class InitialMigration : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Blogs",
c => new
{
ID = c.Int(nullable: false, identity: true),
Content = c.String(maxLength: 4000),
})
.PrimaryKey(t => t.ID);
}
public override void Down()
{
DropTable("dbo.Blogs");
}
}
After running Update-Database I see:
Applying code-based migrations: [201304211225255_InitialMigration].
Applying code-based migration: 201304211225255_InitialMigration.
Running Seed method.
Now the problem appears - in my Server Explorer I examine the database Logo.sdf and it does not include the table Blogs! I even try to run this code from my app:
var db = new LogoContext();
db.Posts.Add(new Blog { Title= "moo" });
db.SaveChanges();
to check if maybe my Server Explorer isn't showing the table.. but I get an exception:
The specified table does not exist. [ Blogs ]
So the migrations are obviously not being applied to my Logo.sdf file :(
If I remove the connection string from app.config, the connection to a local instance of SQL Server Express is assumed. And there it works flawlessly!! When I examine the database with SQL Server Management Studio, I see the new Blogs table and also a system table for metadata about migrations...
Another little piece of information:
When I try to run Update-Database again, I get "No pending code-based migrations." and that tells me that some data is being saved to Logo.sdf after all... at least some metadata about migrations, but still I can't see that table in Server Explorer.
I'm using VS 2012 and EF 5.0.
Please help me understand this... It looks to me that something is seriously wrong because it just works with SQL Server Express instance, but not with SQL Server CE 4.0. :((
Thank you!
david
So the problem was that the solution created a separate .sdf file here:
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Logo.sdf"
Which was unexpected and strange IMHO...
I ended up using this connection string:
<add name="LogoContext" connectionString="Data Source=|DataDirectory|\Logo.sdf" providerName="System.Data.SqlServerCE.4.0"/>
This references bin/Debug/Logo.sdf and it works during development and when running a .exe separately.
The only thing with this way is that my Logo.sdf project file (which was getting copied to Debug "if newer") is now completely ignored. All the migrations will be run on the Debug file.. That's probably good too....
Thanx Erik for the hint!
david

Categories