Click here to Skip to main content
15,173,640 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi I have a problem with un-assigning a user from a Job. i.e I don't know how to delete a registration record related to the job that the user is assigned to. To make it more simple I have 3 tables with this relationship.

tblUser 1---------M tblRegistration M -----------1 tblJob

See this image of the form? Basically the end user clicks the big orange button "Unassign" and the record disappears from the table and appears in the table with the Unassigned Users heading.

https://imgur.com/jgVnTpQ

My problem is in the UnassignUserRegistration method where I am trying to delete my user registration which In my Job Controller. I will provide the code.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Pitcher.Data;
using Pitcher.Models;
using Pitcher.Models.TeamViewModels;


namespace Pitcher.Controllers
{
    public class JobsController : Controller
    {
        private readonly TeamContext _context;


        public JobsController(TeamContext context)
        {
            _context = context;
        }
       
        /// <summary>
        /// Creates a Registration to assign user to a currently displayed job.
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="JobID"></param>
        /// <returns>The newly assigned user registration</returns>
        [HttpGet]
        public async Task<IActionResult> AssignUserRegistration(int UserID, int JobID)
        {
            Registration registration = new Registration{UserID = UserID, JobID = JobID, RegistrationDate = DateTime.Now};
            _context.Add(registration);
            await _context.SaveChangesAsync();
            //ID is JobID. Now refresh the page by redirecting to it again.
            return RedirectToAction(nameof(UserAssignments), new{ID = JobID});
        }


        public IActionResult GetUnassignedUsers()
        {
            _context.Jobs.OrderByDescending(j => j.ID).FirstOrDefault();       
            var userlist = _context.Users.Where(u => !u.Registrations.Any());
            return Json(userlist);
        }


        public IActionResult GetAssignedUsers()
        {
            _context.Jobs.OrderByDescending(j => j.ID).FirstOrDefault();       
            var userlist = _context.Users.Where(u => u.Registrations.Any());
            return Json(userlist);
        }


        public async Task<IActionResult> UnassignUserRegistration(int UserID, int JobID)
        {            
            if(JobID == null)
            {
                return NotFound();
            }
            var registration = await _context.Registrations.OrderByDescending(j => j.ID)                
                .AsNoTracking()
                .Include(r => r.Job)
                .Include(r => r.User)
                //Retrives the selected entity.
                .FirstOrDefaultAsync(m => m.ID == JobID);
            if (registration == null)
            {
                ViewData["ErrorMessage"] =
                    "Delete failed. Try again, and if the problem persists " +
                    "see your system administrator.";
            }
            return RedirectToAction(nameof(UserAssignments), new{ID = JobID});
        }


        [HttpPost, ActionName("UnassignUserRegistration")]
        [ValidateAntiForgeryToken]
        //This is basically like the Delete_Confirmed method that 
        //EF Core generates with the view which I don't supply as 
        //as it is a given that it should work if UnassignUserRegistration does. 
        public async Task<IActionResult> UnassignUserRegistration_Confirmed(int id)
        {
            var registration = await _context.Registrations.FindAsync(id);


            if(registration == null)
            {
                return RedirectToAction(nameof(Index));
            }
            try
            {
                _context.Registrations.Remove(registration);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            catch(DbUpdateException /* ex */)
            {
                //Log the error (uncomment ex variable name and write a log.)
                return RedirectToAction(nameof(Delete), new {id = id, saveChangesError = true});
            }
        }

In the view file the method is being triggered in the second return of the the registeredUserTable. Here is all the code if you
need to see it. Here is the function I am rendering the table data to in the front end.


ASP.NET
document.getElementById('registeredUsersTable').style.display = 'block';
var id=@Model.ID
$('#registeredUsersTable').DataTable({
    "ajax": {
    'type': 'get',
    //PROBLEM:Cannot get the related UserID of the Job.
    'data': { ID: id},
    'dataType': "json",
    "url": "@Url.Action("GetAssignedUsers")",
    "dataSrc": function (result) {
        return result;
        }
    },
    "columns": [
    { "data": "userFirstName"},
    { "data": "userLastName"},
    { "data": "userContactEmail"},
    {
    "data": null,
    "render": function (value) {
        return  '<a href="/Jobs/UnassignUserRegistration?UserID=' + value.id + '&JobID=' + id +' "button type="button" class="btn btn-primary btn-block">Unassign</a>';
    }
        }
    ]
});


What I have tried:

I looked all over online and used the original ASP.NET 5 Data Access Tutorial for MVC on Microsoft. The code samples are completely different to mine as I am attempting to pass different parameters.
Posted
Updated 14-Apr-21 16:34pm
v2

1 solution

Some general comments:

<blockquote class="quote"><div class="op">Quote:</div>_context.Jobs.OrderByDescending(j => j.ID).FirstOrDefault(); </blockquote>


Doesn't do anything -- you're not assigning the result to a variable that you're using.

if(JobID == null)
            {
                return NotFound();
            }


JobID is an int, not a nullable int int? Doesn't the compiler warn you that the null check is pointless?

As to your question:
Quote:
My problem is in the UnassignUserRegistration method where I am trying to delete my user registration which In my Job Controller.


I'm confused. The code looks like it's intended to find the job associated with the user, and returns the JobID, not the Registration ID, for confirmation. So it looks like it's the JobID, not the RegistrationID, that is being passed in to UnassignUserRegistration_Confirmed. So that seems to me to be the first place I'd look.
   
Comments
Jordan Nash 15-Apr-21 6:51am
   
My intention was to return the RegistrationID here which will be deleted though obviously that's not what I'm doing here because I don't know how to. Essentially the reason why you are confused is because I was confused.

I was trying to base my deletion method on the AssignUserRegistration method using the two parameters and do the reverse of that and also base it on the Delete actions generated by EF Core by default. Yes the null check is pointless and the compiler warned me. You could say I didn't know what to check for. At this point I am staring at the problem. I realize now I don't have to check for the UserID or JobId as EF Core will do a cascade delete so really I just have to work on the RegistrationID and workout how to delete it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900