InvalidOperationException: No service for type 'Attempt7.Models.User' has been registered

Viewed 32

I am trying to Insert a new record into my database. But when try to add a "User" of any role, I get the following error, Screenshot. For my class layout, I have a "User" class, and then the subclasses, Parent/SubjectCoordinator/Teacher/Secretary/Student. I'm using EF6, VS2022, C#. What could be the possible cause of it? Thanks.

This is my program.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.Cookies;
using Attempt7.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);
string connString = builder.Configuration.GetConnectionString("DefaultConnection");

// Add services to the container.
builder.Services.AddControllersWithViews();

builder.Services.AddSession();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

builder.Services.AddControllers();

builder.Services.AddDbContext<ApplicationDBContext>(options =>
{
   options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
   app.UseExceptionHandler("/Home/Error");
   // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
   app.UseHsts();
}
app.UseSession();

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseSession();

app.UseEndpoints(endpoints =>
{
   endpoints.MapControllers();
});

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

app.Run();

This is my User Class

public abstract class User
   {
       [Key]
       public int UserID { get; set; }

       public string Name { get; set; }

       [Required]
       public string Surname { get; set; }

       public DateTime DOB { get; set; }

       public string Gender { get; set; }

       public string CellNumber { get; set; }

       [Required(ErrorMessage = "This field is required")]
       [DataType(DataType.Password)]
       public string Password { get; set; }

       [Required(ErrorMessage = "This field is required")]
       public string Email { get; set; }

       public string AddressLine1 { get; set; }

       public string AddressLine2 { get; set; }

       public int SuburbID { get; set; }

       public DateTime DateHired { get; set; }

       public string Title { get; set; }

       public int RoleID { get; set; }

       public string AlternativeContactNumber { get; set; }

       public string AlternativeContactFullName { get; set; }

       public string ErrorMessage { get; set; } = "";      

       public virtual Suburb Suburb { get; set; }

       [ForeignKey(nameof(RoleID))]
       public virtual Role Role { get; set; }
   }

This is my Teacher Class.

public class Teacher : User
   {
       [Required]
       public DateTime DateJoined { get; set; } = DateTime.Now;

       [StringLength(1)]
       [Required]
       public char Is_Active { get; set; } = 'T';
      
       [ForeignKey("UserID")]
       public virtual User User { get; set; }
   }

This is my Student Class

public class Student : User
    {
        
        [Required]
        public DateTime DateJoined { get; set; } = DateTime.Now;

        [StringLength(1)]
        [Required]
        public char Is_Active { get; set; } = 'T'; 
               
        [ForeignKey("UserID")]       
        public virtual User User { get; set; }
    }

The other 3 subclasses are similar with the difference being their unique properties.

And this is the controller action I'm calling

public IActionResult Create()
        {
            ViewData["RoleID"] = new SelectList(_db.Role, "RoleID", "RoleName");
            ViewData["SuburbID"] = new SelectList(_db.Suburb, "SuburbID", "SuburbID");
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([FromServices][Bind("UserID,Name,Surname,DOB,Gender,CellNumber,Password,Email,AddressLine1,AddressLine2,SuburbID,DateHired,Title,RoleID,AlternativeContactNumber,AlternativeContactFullName,ErrorMessage")] User user)
        {
            int SelectedRole = user.RoleID; 
            
            if (ModelState.IsValid)
            {         
                if (SelectedRole == 1)//Student
                {
                    Student student = new Student();
                    student = (Student)user;

                    _db.Add(student);
                }
                else if (SelectedRole == 2)//Teacher
                {
                    Teacher teacher = new Teacher();
                    teacher = (Teacher)user;

                    _db.Add(teacher);
                }
                else if (SelectedRole == 3)//SubjectCoordinator
                {
                    SubjectCoordinator subjectcoordinator = new SubjectCoordinator();
                    subjectcoordinator = (SubjectCoordinator)user;

                    _db.Add(subjectcoordinator);
                }
                else if (SelectedRole == 4)//Parent
                {
                    Parent parent = new Parent();
                    parent = (Parent)user;

                    _db.Add(parent);
                }
                else if (SelectedRole == 5)//Secretary
                {
                    Secretary secretary = new Secretary();
                    secretary = (Secretary)user;

                    _db.Add(secretary);
                }


                await _db.SaveChangesAsync();
                return RedirectToAction("Index");
            }
            ViewData["RoleID"] = new SelectList(_db.Role, "RoleID", "RoleName", user.RoleID);
            ViewData["SuburbID"] = new SelectList(_db.Suburb, "SuburbID", "SuburbID", user.SuburbID);
            return View(user);
        }

I'm using an generated view.


@model Attempt7.Models.User

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

<h1>Create</h1>

<h4>User</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="RoleID" class="control-label"></label>
                <select asp-for="RoleID" class ="form-control" asp-items="ViewBag.RoleID"></select>
            </div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Surname" class="control-label"></label>
                <input asp-for="Surname" class="form-control" />
                <span asp-validation-for="Surname" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="DOB" class="control-label"></label>
                <input asp-for="DOB" class="form-control" />
                <span asp-validation-for="DOB" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Gender" class="control-label"></label>
                <input asp-for="Gender" class="form-control" />
                <span asp-validation-for="Gender" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="CellNumber" class="control-label"></label>
                <input asp-for="CellNumber" class="form-control" />
                <span asp-validation-for="CellNumber" class="text-danger"></span>
            </div>-->
            <div class="form-group">
                <label asp-for="Password" class="control-label"></label>
                <input asp-for="Password" class="form-control" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Email" class="control-label"></label>
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="AddressLine1" class="control-label"></label>
                <input asp-for="AddressLine1" class="form-control" />
                <span asp-validation-for="AddressLine1" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="AddressLine2" class="control-label"></label>
                <input asp-for="AddressLine2" class="form-control" />
                <span asp-validation-for="AddressLine2" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="SuburbID" class="control-label"></label>
                <select asp-for="SuburbID" class ="form-control" asp-items="ViewBag.SuburbID"></select>
            </div>
            <div class="form-group">
                <label asp-for="DateHired" class="control-label"></label>
                <input asp-for="DateHired" class="form-control" />
                <span asp-validation-for="DateHired" class="text-danger"></span>
            </div>-->
            <div class="form-group">
                <label asp-for="Title" class="control-label"></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="AlternativeContactNumber" class="control-label"></label>
                <input asp-for="AlternativeContactNumber" class="form-control" />
                <span asp-validation-for="AlternativeContactNumber" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="AlternativeContactFullName" class="control-label"></label>
                <input asp-for="AlternativeContactFullName" class="form-control" />
                <span asp-validation-for="AlternativeContactFullName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

This is also the layout of my User table Screenshot in SQL Server

0 Answers
Related