简体   繁体   中英

How to Define and use Different User Types in ASP.NET Core

The application has the following users and controller in ASP.NET Core 2.1.

AppUser

using Microsoft.AspNetCore.Identity;

namespace MyApp.Models
{
    public class AppUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

DifferentUser

namespace MyApp.Models
{
    public class DifferentUser : AppUser
    {
        public string Property1 { get; set; }
    }
}

DifferentUserController.cs

using System.Threading.Tasks;
using MyApp.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

    namespace MyApp.Controllers
    {
        [Authorize(Roles = "DifferentUser")]
        public class DifferentUserController : Controller
        {

            private UserManager<AppUser> userManager;

            public DifferentUserController(UserManager<AppUser> _userManager)
            {
                userManager = _userManager;
            }

            [HttpGet]
            public async Task<IActionResult> Index()
            {
                var user = (DifferentUser) await userManager.GetUserAsync(HttpContext.User);
                return View("~/Views/DifferentUser/Index.cshtml", user);
            }
        }
    }

Within the DifferentUserController, the Index method should return the view, and pass it the currently logged in DifferentUser. But it returns the following error.

InvalidCastException: Unable to cast object of type 'MyApp.Models.AppUser' to type 'MyApp.Models.DifferentUser'.

What is the correct/best way of handling different user types in ASP.NET Core 2.1?

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MyApp.Models;
using MyApp.Infrastructure;
using Microsoft.AspNetCore.Identity;

namespace MyApp
{
    public class Startup
    {

        public Startup(IConfiguration configuration) =>
            Configuration = configuration;

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IPasswordValidator<AppUser>,
                CustomPasswordValidator>();

            services.AddTransient<IUserValidator<AppUser>,
                CustomUserValidator>();

            services.AddDbContext<AppIdentityDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<AppUser, IdentityRole>(opts => {
                opts.User.RequireUniqueEmail = true;
                opts.Password.RequiredLength = 6;
                opts.Password.RequireNonAlphanumeric = false;
                opts.Password.RequireLowercase = false;
                opts.Password.RequireUppercase = false;
                opts.Password.RequireDigit = false;
            }).AddEntityFrameworkStores<AppIdentityDbContext>()
                .AddDefaultTokenProviders();

            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseStatusCodePages();
            app.UseDeveloperExceptionPage();
            app.UseStaticFiles();
            app.UseAuthentication();
            app.UseMvcWithDefaultRoute();
        }
    }
}

To avoid the need to cast, you could use an enum to define your user type and use your AppUser class in both cases. This will make it possible in this scenario.

public class AppUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public UserType Type { get; set; }

    public enum UserType {
        User,
        OtherUser
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM