Create + Assign + List + Edit + Complete operations and role-wise views (Admin / Manager / User) are supported by the ASP.NET Core MVC project (SQL Server + EF Core + Identity). I'll provide a finished, opinionated beginning project below that you can copy and run into a new solution. To make it function right out of the box, I made sensible defaults:

Defaults I used

  • .NET 8 / ASP.NET Core MVC (minimal hosting Program.cs).
  • EF Core with SQL Server (use LocalDB or your SQL Server instance).
  • ASP.NET Identity for users & roles (Admin / Manager / User).
  • Entity: TaskItem with create/assign/edit/complete flows.
  • Role-wise view behavior:
    • Admin: sees all tasks and can manage them + manage users/roles.
    • Manager: sees tasks they created + tasks assigned to users in their team (simple demo: managers can view all tasks but UI filters for managers).
    • User: sees only tasks assigned to them.
  • Seeded roles + initial admin user automatically on startup.
  • EF Migrations recommended (I show commands).

Below are the main files — copy them into a new project (or I can generate more files if required). I included the essential Controllers, Models, DbContext, Program, Views examples, and steps to run.

1. Create the project

From a terminal:
dotnet new mvc -n TaskManagerApp
cd TaskManagerApp
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore

2. appsettings.json
Add a SQL Server connection string (LocalDB used here):
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=TaskManagerAppDb;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}


3. Models
Models/ApplicationUser.cs
using Microsoft.AspNetCore.Identity;
using System.Collections.Generic;

namespace TaskManagerApp.Models
{
    public class ApplicationUser : IdentityUser
    {
        // Example extra property
        public string FullName { get; set; }

        // Optional: list of tasks assigned
        public ICollection<TaskItem> AssignedTasks { get; set; }
    }
}


Models/TaskItem.cs
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace TaskManagerApp.Models
{
    public enum TaskStatus
    {
        Pending,
        InProgress,
        Completed
    }

    public class TaskItem
    {
        [Key]
        public int Id { get; set; }

        [Required, StringLength(200)]
        public string Title { get; set; }

        public string Description { get; set; }

        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        public DateTime? DueDate { get; set; }

        public TaskStatus Status { get; set; } = TaskStatus.Pending;

        // assigned user
        public string AssignedUserId { get; set; }

        [ForeignKey("AssignedUserId")]
        public ApplicationUser AssignedUser { get; set; }

        // who created the task (user id)
        public string CreatedByUserId { get; set; }
    }
}

4. Data / DbContext
Data/AppDbContext.cs

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using TaskManagerApp.Models;

namespace TaskManagerApp.Data
{
    public class AppDbContext : IdentityDbContext<ApplicationUser>
    {
        public AppDbContext(DbContextOptions<AppDbContext> opts) : base(opts) { }

        public DbSet<TaskItem> TaskItems { get; set; }
    }
}


5. Program.cs (minimal hosting) — seeds roles & admin
Program.cs

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using TaskManagerApp.Data;
using TaskManagerApp.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(connectionString));

builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequireUppercase = false;
})
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

builder.Services.AddControllersWithViews();

var app = builder.Build();

// Ensure DB and seed roles
using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    var db = services.GetRequiredService<AppDbContext>();
    db.Database.Migrate();

    // Seed roles and admin user
    var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
    var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();

    string[] roles = new[] { "Admin", "Manager", "User" };
    foreach (var r in roles)
    {
        if (!await roleManager.RoleExistsAsync(r))
            await roleManager.CreateAsync(new IdentityRole(r));
    }

    // create default admin
    var adminEmail = "[email protected]";
    var admin = await userManager.FindByEmailAsync(adminEmail);
    if (admin == null)
    {
        admin = new ApplicationUser { UserName = "admin", Email = adminEmail, EmailConfirmed = true, FullName = "System Admin" };
        var result = await userManager.CreateAsync(admin, "Admin@123"); // change for prod
        if (result.Succeeded)
        {
            await userManager.AddToRoleAsync(admin, "Admin");
        }
    }
}

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Tasks}/{action=Index}/{id?}");

app.Run();


6. TasksController (main CRUD + assign + complete + role-wise list)
Controllers/TasksController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TaskManagerApp.Data;
using TaskManagerApp.Models;

namespace TaskManagerApp.Controllers
{
    [Authorize]
    public class TasksController : Controller
    {
        private readonly AppDbContext _db;
        private readonly UserManager<ApplicationUser> _userManager;

        public TasksController(AppDbContext db, UserManager<ApplicationUser> userManager)
        {
            _db = db;
            _userManager = userManager;
        }

        // Role-wise listing
        public async Task<IActionResult> Index(string status = null)
        {
            var user = await _userManager.GetUserAsync(User);
            var roles = await _userManager.GetRolesAsync(user);
            IQueryable<TaskItem> query = _db.TaskItems.Include(t => t.AssignedUser);

            if (roles.Contains("Admin"))
            {
                // Admin sees all - optionally filter by status
            }
            else if (roles.Contains("Manager"))
            {
                // Manager sees tasks they created OR assigned to any user
                query = query.Where(t => t.CreatedByUserId == user.Id || t.AssignedUserId != null);
            }
            else
            {
                // Regular user sees only tasks assigned to them
                query = query.Where(t => t.AssignedUserId == user.Id);
            }

            if (!string.IsNullOrEmpty(status) && Enum.TryParse<TaskStatus>(status, out var st))
            {
                query = query.Where(t => t.Status == st);
            }

            var list = await query.OrderByDescending(t => t.CreatedAt).ToListAsync();
            return View(list);
        }

        // GET: Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(TaskItem model)
        {
            var user = await _userManager.GetUserAsync(User);
            if (ModelState.IsValid)
            {
                model.CreatedAt = DateTime.UtcNow;
                model.CreatedByUserId = user.Id;
                _db.TaskItems.Add(model);
                await _db.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(model);
        }

        // GET: Edit
        public async Task<IActionResult> Edit(int id)
        {
            var task = await _db.TaskItems.FindAsync(id);
            if (task == null) return NotFound();
            return View(task);
        }

        // POST: Edit
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, TaskItem model)
        {
            var task = await _db.TaskItems.FindAsync(id);
            if (task == null) return NotFound();

            if (ModelState.IsValid)
            {
                task.Title = model.Title;
                task.Description = model.Description;
                task.DueDate = model.DueDate;
                task.Status = model.Status;
                task.AssignedUserId = model.AssignedUserId;
                await _db.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(model);
        }

        // GET: Assign (simple assignment UI)
        public async Task<IActionResult> Assign(int id)
        {
            var task = await _db.TaskItems.FindAsync(id);
            if (task == null) return NotFound();

            var users = await _userManager.Users.ToListAsync();
            ViewBag.Users = users;
            return View(task);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Assign(int id, string assignedUserId)
        {
            var task = await _db.TaskItems.FindAsync(id);
            if (task == null) return NotFound();
            task.AssignedUserId = assignedUserId;
            task.Status = TaskStatus.InProgress;
            await _db.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        // Mark complete
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Complete(int id)
        {
            var task = await _db.TaskItems.FindAsync(id);
            if (task == null) return NotFound();
            task.Status = TaskStatus.Completed;
            await _db.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        // Details
        public async Task<IActionResult> Details(int id)
        {
            var t = await _db.TaskItems.Include(x => x.AssignedUser).FirstOrDefaultAsync(x => x.Id == id);
            if (t == null) return NotFound();
            return View(t);
        }

        // Delete (Admin only)
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult> Delete(int id)
        {
            var t = await _db.TaskItems.FindAsync(id);
            if (t == null) return NotFound();
            _db.TaskItems.Remove(t);
            await _db.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
    }
}


7. Views (Razor) — minimal examples
Place under Views/Tasks/

Index.cshtml
@model IEnumerable<TaskManagerApp.Models.TaskItem>
@using TaskManagerApp.Models
@inject Microsoft.AspNetCore.Identity.UserManager<TaskManagerApp.Models.ApplicationUser> UserManager
@{
    ViewData["Title"] = "Tasks";
}

<h2>Tasks</h2>

<p>
    <a asp-action="Create" class="btn btn-primary">Create Task</a>
</p>

<table class="table table-striped">
    <thead>
        <tr>
            <th>Title</th>
            <th>Assigned To</th>
            <th>Status</th>
            <th>Due</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach(var t in Model) {
    <tr>
        <td>@t.Title</td>
        <td>@(t.AssignedUser?.FullName ?? t.AssignedUser?.UserName ?? "Unassigned")</td>
        <td>@t.Status</td>
        <td>@(t.DueDate?.ToLocalTime().ToString("yyyy-MM-dd") ?? "-")</td>
        <td>
            <a asp-action="Details" asp-route-id="@t.Id">Details</a> |
            <a asp-action="Edit" asp-route-id="@t.Id">Edit</a> |
            <a asp-action="Assign" asp-route-id="@t.Id">Assign</a>
            <form asp-action="Complete" asp-route-id="@t.Id" method="post" style="display:inline">
                <button type="submit" class="btn btn-link">Complete</button>
            </form>
        </td>
    </tr>
}
    </tbody>
</table>


Create.cshtml (simple)
@model TaskManagerApp.Models.TaskItem
@{
    ViewData["Title"] = "Create Task";
}
<h2>Create Task</h2>

<form asp-action="Create" method="post">
    <div class="form-group">
        <label asp-for="Title"></label>
        <input asp-for="Title" class="form-control" />
        <span asp-validation-for="Title" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Description"></label>
        <textarea asp-for="Description" class="form-control"></textarea>
    </div>
    <div class="form-group">
        <label asp-for="DueDate"></label>
        <input asp-for="DueDate" type="date" class="form-control" />
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
</form>


Assign.cshtml

@model TaskManagerApp.Models.TaskItem
@{
    ViewData["Title"] = "Assign Task";
    var users = ViewBag.Users as List<TaskManagerApp.Models.ApplicationUser>;
}
<h2>Assign Task: @Model.Title</h2>

<form asp-action="Assign" method="post">
    <input type="hidden" asp-for="Id" />
    <div class="form-group">
        <label>Select User</label>
        <select name="assignedUserId" class="form-control">
            <option value="">-- Unassigned --</option>
            @foreach(var u in users)
            {
                <option value="@u.Id" @(u.Id == Model.AssignedUserId ? "selected" : "")>@u.FullName ?? u.UserName</option>
            }
        </select>
    </div>
    <button class="btn btn-primary" type="submit">Assign</button>
</form>


Edit.cshtml and Details.cshtml are straightforward — follow the pattern above (bind fields and show status dropdown).

8. Identity / Account pages

You can scaffold Identity pages (Register/Login) or rely on the default templates. For simplicity you can scaffold or add links to /Identity/Account/Login. In production, scaffold the pages to capture FullName during registration and to allow role assignment (Admin page for user/role management).

9. Database migrations

From terminal:
dotnet ef migrations add InitialCreate
dotnet ef database update


This will create the DB and tables. Program.cs seeds roles + admin user.

10. Additional suggestions for role-wise UX & security

  • Add [Authorize(Roles="Admin,Manager")] attributes where appropriate.
  • Create an Admin area (Area = Admin) for user & role management using RoleManager + UserManager.
  • For manager-team relationships you might add a Team entity and a ManagerId to associate users with managers.
  • For large teams add paging, search, and assignment by team.

11. How to run

  • Update connection string in appsettings.json to point to your SQL Server (LocalDB works).
  • dotnet ef database update (or let Program.cs migrate on startup).
  • dotnet run
  • Login with seeded admin: [email protected] / Admin@123 (change immediately in production).