How to recreate initial ASP.NET Identity Tables? - c#

I went to upgrade our ASP.NET Web Forms solution from Identity 1.x to Identity 2.0. I updated the three Identity 2.0 packages. I then went to work on implementing Password Reset, etc. I didn't realize I had to Update the Database. That migration failed because the tables were in the wrong context. We decided to start over. We deleted the tables but they are not getting recreated when I access the Login page. How do I get these tables regenerated or should I create them manually?

Try disabling the schema consistency. This is one time thing that needs to happen when you upgrade asp.net identity from version 1.0 to 2.0.
public ApplicationDbContext() : base("MyConnection", throwIfV1Schema:false)
Notice I added throwIfV1Schema:false as a second parameter. Compile it, try to log in so the DB gets updated, do the migrations if needed and then you can remove it.

Related

How to modify asp.net Identity UI for asp.net core WebAPI with angular

I started learning .net core a few days ago and as a start, I created a .netcore project with an inbuilt angular 8 templates.
It has a couple of pages built in angular, like counter and fetches data, etc, but all the Identity-related pages (login, registration, etc) are coming as a plain HTML from the backend. So "my main Concern is making some UI changes in that page".
I found out that the identity has been added to the class library and hence not visible in the backend code. and In order to make changes to it, I will need to first add it to the code by regenerating it through scaffolding. this will override the previous library code and can be modified as per requirement.
So I selected add new scaffolded item --> identity. and selected "override all files" in first attempt and "account\login" and "account\register" only in the second attempt, and applicationdbcontext for dbcontext. but unfortunately neither worked for me.
When I try to build the code I get this error
Error CS0246 The type or namespace name 'IWebHostEnvironment' could not be found (are you missing a using directive or an assembly reference?)
C:\Users\MyUserName\source\repos\MyProjectName\obj\Debug\netcoreapp3.0\Razor\Pages\Shared\_Layout.cshtml.g.cs 448
I don't really know what .g.cs extension is, there is no import statement on that page and some weird code that I have never seen before. the page itself also doe's not shown any error/red marking.
I basically want to achieve two things here,
1) using .net core app completely as an API, I want to build UI for all the login related stuff in angular itself rather than getting as an HTML from the back-end.
2) adding a few more fields in the user login form. and since it is code first approach then ultimately making changes in users DBSet (which I don't know how to do in this case).
I have not added any code sample as it is a kind of straight forward problem/question. to reproduce the issue just create a project in .net core 3.0 and take an angular 8 templates. now try to make any UI related change on login or register page.
It's annoying that this piece which isn't necessary in the layout for a default project lives there.
Try to drop that import and that default app with scaffolded UI will work OK.
My intention was to add some styles for the Login page which is a bit boring.
What have I done?
+ created an ASP.NET Core web application with Angular and Authentication (Individual User Accounts) template (from Visual Studio 2019).
+ Add New Scaffolded Item -> Identity
+ Followed the steps from ScaffoldingReadme.txt file (some steps have already snippets in the correct place and does not require any additions)
+ Remove the line #inject IWebHostEnvironment Environment and Microsoft.AspNetCore.Hosting from the _Layout.cshtml page;
+ READY to see the RESULT :)
just check the guide from https://devblogs.microsoft.com/aspnet/aspnetcore-2-1-identity-ui/ and it also applies to new core 3 angular 8 Template project which have also Angular authentication support.
one thing that is a little different was the public async Task OnPostAsync() method on Areas.Identity.Pages.Account.Manage.Index.cshtml.cs file which is for supporting updating the name of the user in its profile.
So comparing your scaffolded template with below sample may help which uses UpdateAsync instead of previous simple single SetPhoneNumberAsync call.
if (Input.PhoneNumber != phoneNumber || Input.Name != user.FullName)
{
user.FullName = Input.Name;
user.PhoneNumber = Input.PhoneNumber;
var updateProfileResult = await _userManager.UpdateAsync(user);
if (!updateProfileResult.Succeeded)
{
throw new InvalidOperationException($"Unexpected error ocurred updating the profile for user with ID '{user.Id}'");
}
}

Associate data to default ASP.NET UAM user using Entity Framework Core

Trying to create a simple MVC application that has basic user account management with social account sign-up.
Created ASP.NET Core 2.2 app with individual authentication, added EF core via NuGet (sqlserver and tools). I have built some basic ASP.NET MVC apps and MVC apps in other languages previously.
I got Facebook login to work per this tutorial.
Now I'm lost.
There's a "Data" directory with a bunch of code in it already, and the normal MVC directories. However, I don't see the MVC files that would correlate to any of the pages or actions associated with the account management I can clearly access when I launch the application, including /Identity/Account/Login, /Identity/Account/Manage, /Identity/Account/Manage/SetPassword, etc.
While having all of this functionality up and running in minutes is cool, already I'm at a disadvantage of not knowing how or why it works. Searching for anything I would expect to shed some light on this gives me technical documentation that makes my head spin and provides zero enlightenment.
I want to have a collection of data sets ("Books") associated to each user. One User to many Books. Given that the User (account?) model is not in the Models directory of the MVC application I don't think that's where it's supposed to be added. And if it is, I don't know how to create that association with the User.
This is what I'm seeing in a file called ApplicationDbContextModelSnapshot.cs
namespace Bookshelf.Data.Migrations
[DbContext(typeof(ApplicationDbContext))]
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
...
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles");
});
... and so on, which looks fairly readable, but does not match up to any of the tutorials I've seen so far.
TL;DR:
Where/how do I correctly create a new models? Is it like this in the Models directory (how I'm used to) or is this obsolete?
Either way, how do I correctly associate data with a user given the baked-in user account management for ASP.NET Core 2.2?
There's a "Data" directory with a bunch of code in it already, and the normal MVC directories. However, I don't see the MVC files that would correlate to any of the pages or actions associated with the account management I can clearly access when I launch the application, including /Identity/Account/Login, /Identity/Account/Manage, /Identity/Account/Manage/SetPassword, etc.
This is because from ASP.NET Core 2.1 Identity is being provided as Razor Class Library with the ASP.NET Core project templates. If you want to see those Identity related codes and customize then you have to Scaffold Identity in your project.
Here is more details about this: Scaffold Identity in ASP.NET Core projects
Moreover if you need ASP.NET Core Identity in MVC format then here is my GitHub Repository where Razor Page Identity has been converted to MVC in ASP.NET Core 2.2.

How do I resolve my Invalid object name 'dbo.AspNetUsers' error?

I changed my connection string when starting a new mvc project because I needed to use some info out of an existing database. Now I get a "Invalid object name 'dbo.AspNetUsers' when I try to load the startup page. A quick google search says the issue happens because you are connecting to an existing database using asp.net users. Still, this should not occur since I am not using code first migrations, right? What is more, I am using Active Directory to authenticate my users instead of individual user accounts.
In addition, the AspNetUserstable does not exist in the database I am calling in the web.config:
Due to the fact that I am not using the UserStore or the ApplicationUser provided by the Individual User Accounts defaults I needed to change this:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
to
public class ApplicationDbContext : DbContext
Optionally If you are using Code First Migrations you could add the initial migrations, remove all of the sql code from the up and down methods, and finally update the database. Even though the tables will still not exist it seems to satisfy the compiler and your project as the error goes away and the page loads as expected.

Unable to Update Model from Database using EF 6 and Visual Studio 2015 Update 3

Right click on the EF Model Designer surface and choose Update Model from Database.
In the dialog box that pops up, you should be able to browse the database, and select objects to add. But in this case, nothing can be selected:
Removing the Connection String from the App.Config and allowing the Designer to re-add it did not resolve the issue.
The credentials used in the Connection String when copied and pasted in SSMS.
The database can be browsed from the VS Server Explorer window.
Creating a new blank EF project and repeating from there works fine.
What could be causing this?
One of 2 problems exist, the Model already has the Tables/SP/View you are looking for or the Login does not have the Authority the access those Tables/SP/View.
One of the factor unable to select any checkbox in Update Wizard is you don't have any updates in your database, therefore entity framework doesn't allow you to select.
If your scenario is not the factor above, you may try the method I listed below:
I had this issue too and I noticed that I didn't grant the db_owner under Database role membership for my database (eg 22Aug_M) in Microsoft SQL Server Management Studio.
After I checked it and it works as normal.

Does Identity Owin require LazyLoading?

tl;dr: Identity seems to require that LazyLoading NOT be disabled; is this true, and what is the cleanest workaround?
I did some basic A-B testing on a simple C# ASP.NET 4.5.1 MVC-5 web application using EntityFramework 6.0.2, Identity EntityFramework 1.0.0, and Identity Owin 1.0.0 and it appears that Owin requires that lazy loading is NOT disabled in the ApplicationContext constructor.
To replicate the issue just make a quick MVC app using Visual Studio 2013, use the MVC template, leave everything at the defaults except uncomment the line: 'app.UseGoogleAuthentication();' in App_Start/Startup.Auth.cs. Run the app and use Google to login, complete the abbreviated registration page it takes you to and go to account/manage. You should see 2 buttons for Google at the bottom. Stop the app.
Now go to ApplicationContext.cs and change the constructor as shown in this code snippet:
public ApplicationContext() : base("DefaultConnection") { } //Works!
public ApplicationContext() : base("DefaultConnection")
{
this.Configuration.LazyLoadingEnabled = false;
} //Does not work
Retry the test. Only 1 Google button should be visible. With LazyLoadingEnabled = false the User Roles, Logins (poss Claims also) aren't loaded.
My theory is that this is a Microsoft oversight/'future feature' as Identity EntityFramework and Identity Owin are both version 1.0.0.
My question is, can this test be confirmed, and what is the cleanest work around?
For my purposes I will just use .ToList() and other methods for forcing EagerLoading when I want to use it. I don't truly need LazyLoading disabled, it's just a safer way to code if you want to always use eager loading. i.e. you miss one spot, it makes it to production, and you have a nice bug where in some View you are iterating through a Model and for Model.x.y y == null and the database connection has been disposed.
Let's not get into Identity vs. other (more robust) methods, or:
using (DatabaseContext) { //Database query }
or calling dispose on every method vs letting the connection be disposed automatically. This is a scenario where you have to use Identity Owin, and dispose of all database calls ASAP. There ought to be something I'm missing, or maybe Identity really is just that incomplete right now.
Yes this was a bug we have fixed in the 2.0.0-alpha1 release. With lazyLoading explicitly disabled prior, EF would not load the associated user entities automatically (logins/claims/roles)

Categories

Resources