How to merge Identity dbcontext with application context?

asp.net-core asp.net-core-identity c# entity-framework-core

Question

I'm not able to read data from Application Identity Users. I'm beginner, any idea? There is no error while compiling. But I cannot add new task.

I get the error while creating a task https://localhost:44312/usertasks/Create

The issue is on GET method but the user lis is not empty

  • Results View Expanding the Results View will enumerate the IEnumerable
  • [0] {lukas@wp.pl} UserTaskTest.Models.ApplicationUser AccessFailedCount 0 int ConcurrencyStamp "785f9a54-e7f1-4e3b-8bad-55165155d631" string Email "lukas@wp.pl" string EmailConfirmed false bool ExecutedUserTasks null System.Collections.Generic.ICollection Id "53f416ab-aa1e-465f-9dd4-dc32e11914ae" string LockoutEnabled true bool LockoutEnd null System.DateTimeOffset? NormalizedEmail "LUKAS@WP.PL" string NormalizedUserName "LUKAS@WP.PL" string OwnedUserTasks null System.Collections.Generic.ICollection PasswordHash "AQAAAAEAACcQAAAAEIqkXlzky+4i8BsPl5Z4524B3Dj3u0RZMY2Rf5ch5l22GEMj5m0LsVgeWDAavmVO+g==" string PhoneNumber null string PhoneNumberConfirmed false bool SecurityStamp "698529ad-c47c-40f9-bdf3-c4d946cda86a" string TwoFactorEnabled false bool UserName "lukas@wp.pl" string
  • [1] {li@wp.pl} UserTaskTest.Models.ApplicationUser AccessFailedCount 0 int ConcurrencyStamp "1a9064e2-3cc9-4794-9198-81423a5d8cd2" string Email "li@wp.pl" string EmailConfirmed false bool ExecutedUserTasks null System.Collections.Generic.ICollection Id "970839dc-31be-4966-8f06-e664aca3622c" string LockoutEnabled true bool LockoutEnd null System.DateTimeOffset? NormalizedEmail "LI@WP.PL" string NormalizedUserName "LI@WP.PL" string OwnedUserTasks null System.Collections.Generic.ICollection PasswordHash "AQAAAAEAACcQAAAAEM2KiwEfRDomBNiWXHmEtvwWEodfZDb8eaSADOGP2ZralzlnBDZEMQIsOvTk1nHMcw==" string PhoneNumber null string PhoneNumberConfirmed false bool SecurityStamp "0a829111-88d7-4a8a-b65d-5582cecbe67f" string TwoFactorEnabled false bool UserName "li@wp.pl" string

System.NullReferenceException: Object reference not set to an instance of an object.
at
Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetListItemsWithValueField()
at Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetListItems()
at Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetEnumerator()

public class UserTask
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserTaskID { get; set; }

    public string Description { get; set; }

    [ForeignKey("OwnerUserID")]
    public string TaskOwnerId { get; set; }

    [ForeignKey("ExecutorUserID")]
    public string TaskExecutorId { get; set; }

    public virtual ApplicationUser OwnerUserID { get; set; }
    public virtual ApplicationUser ExecutorUserID { get; set; }

}


public class ApplicationUser : IdentityUser
{
     public ICollection<UserTask> OwnedUserTasks { get; set; }
     public ICollection<UserTask> ExecutedUserTasks { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {
    }

    public DbSet<UserTask> UserTask { get; set; }


    protected override void OnModelCreating(ModelBuilder builder)
    {
       base.OnModelCreating(builder);

       builder.Entity<ApplicationUser>()
           .HasMany(x => x.OwnedUserTasks)
           .WithOne(x => x.OwnerUserID);

       builder.Entity<ApplicationUser>()
           .HasMany(x => x.ExecutedUserTasks)
           .WithOne(x => x.ExecutorUserID);
    }
}

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        // Add application services.
        services.AddTransient<IEmailSender, EmailSender>();

        services.AddMvc();
    }
}

UserTaskControler

public class UserTasksController : Controller
{
    private readonly ApplicationDbContext _context;
    private readonly UserManager<ApplicationUser> _userManager;

    public UserTasksController(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
    {
        _context = context;
        _userManager = userManager;
    }

    public IActionResult Create()
    {
        ViewData["TaskOwnerId"] = new SelectList(_userManager.Users.ToList(), "Id", "Name");

        ViewData["TaskExecutorId"] = new SelectList(_userManager.Users.ToList(), "Id", "Name");

        return View();
    }
}

and the view

@model UserTaskTest.Models.UserTask

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<h4>UserTask</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Description" class="control-label"></label>
                <input asp-for="Description" class="form-control" />
                <span asp-validation-for="Description" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="TaskOwnerId" class="control-label"></label>
                 <select asp-for="TaskOwnerId" class="form-control" asp-items="ViewBag.TaskOwnerId"></select>
            </div>
            <div class="form-group">
             <!--   <label asp-for="TaskExecutorId" class="control-label"></label>
                <select asp-for="TaskExecutorId" class="form-control" asp-items="ViewBag.TaskExecutorId"></select> -->
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
1
0
11/25/2017 3:29:20 PM

Popular Answer

_userManager is causing the issue here. It's assuming because of change tracking and the nature of your ForeignKeys that you are trying to alter the User. Attempt to fill your Dropdowns with _dbContext.Users.ToList(), while it doesn't show available in the context that is generated, it's an inheritance gift.

Also Name in your dropdown will error unless you actually created the property in ApplicationUser, since by default it doesn't exist. https://github.com/aspnet/Identity/blob/dev/src/Microsoft.Extensions.Identity.Stores/IdentityUser.cs

public class ApplicationUser : IdentityUser
{
   public string Name {get;set;}  //?? missing?

   public ICollection<UserTask> OwnedUserTasks { get; set; }
   public ICollection<UserTask> ExecutedUserTasks { get; set; }
}
0
11/26/2017 5:17:22 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow