Home > Blockchain >  Foreign Key not showing in dropdown box | MVC
Foreign Key not showing in dropdown box | MVC

Time:11-02

I'm somewhat new to MVC and have been following along with a tutorial but it has no answers regarding my question. For my Create page, the Foreign keys are not showing up. Basically, on the Projects page I created a project, on the People page I created a person. So when I try to create a ProjectRole on the ProjectRoles page, the ProjectId and PersonId are not showing up in the drop-down menu. Down below all of my code, I have provided a screenshot of what I have tried to put into words.

My models:

public class Project
{
    public int Id { get; set; }

    [Required]
    [MaxLength(30)]
    public string Name { get; set; }

    [Required]
    public DateTime StartDate { get; set; }

    [Required]
    public DateTime DueDate { get; set; }

    public ICollection<ProjectRole> ProjectRoles { get; set; }
}

public class Person
{
    public int Id { get; set; }

    [Required]
    [MaxLength(30)]
    public string FirstName { get; set; }

    [Required]
    [MaxLength(30)]
    public string MiddleName { get; set; }

    [Required]
    [MaxLength(30)]
    public string LastName { get; set; }

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

    public ICollection<ProjectRole> ProjectRoles { get; set; }
}
public class ProjectRole
{
    public int Id { get; set; }

    [Required]
    public double HourlyRate { get; set; }

    [ForeignKey("Person")]
    public int PersonId { get; set; }

    [ForeignKey("Project")]
    public int ProjectId { get; set; }

    [ForeignKey("AppRole")]
    public int RoleId { get; set; }

}

My Controller code:

public IActionResult Create()
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,HourlyRate,PersonId,ProjectId,RoleId")] ProjectRole projectRole)
{
    if (ModelState.IsValid)
    {
        _context.Add(projectRole);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(projectRole);
}

And my view code here:

@model Project2.Models.Entities.ProjectRole

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

<h1>Create</h1>

<h4>ProjectRole</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="HourlyRate" class="control-label"></label>
                <input asp-for="HourlyRate" class="form-control" />
                <span asp-validation-for="HourlyRate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="PersonId" class="control-label"></label>
                <select asp-for="PersonId" class ="form-control" asp-items="ViewBag.PersonId"></select>
            </div>
            <div class="form-group">
                <label asp-for="ProjectId" class="control-label"></label>
                <select asp-for="ProjectId" class ="form-control" asp-items="ViewBag.ProjectId"></select>
            </div>
            <div class="form-group">
                <label asp-for="RoleId" class="control-label"></label>
                <input asp-for="RoleId" class="form-control" />
                <span asp-validation-for="RoleId" 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");}
}

Screenshot of example of what I mean:

Screenshot of example of what I mean

CodePudding user response:

I suppose more personable to display the Person Name (and the Project Name) in the select controls, but to pass the PersonId (and ProjectId) to the Create method when click on the Create button.

Therefore, prepare the Person list (and the Project list) like below:

public IActionResult Create()
{
    var persons = new List<SelectListItem>();
    // Iterate through `Persons`
    foreach(var p in _context.Persons)
    {
        persons.Add(new SelectListItem() { Value= p.Id, Text = p.FirstName ", " p.LastName}); 
    }  
    ViewBag.Persons = persons; 

    // Prepare the projects list (like `Persons` list above)
    // ... your code here
    ViewBag.Projects = persons; 

    return View(new ProjectRole(){ /* Add your code here to create the ProjectRole .../* });
}

And in the view:

 <div class="form-group">
    <label asp-for="PersonId" class="control-label"></label>
    <select asp-for="PersonId" class="form-control" asp-items="ViewBag.Persons"></select>
</div>
<div class="form-group">
    <label asp-for="ProjectId" class="control-label"></label>
    <select asp-for="ProjectId" class="form-control" asp-items="ViewBag.Projects"></select>
</div>

For additional information see The Select Tag Helper

*NOTE: And I would recommend to create compound view model to include all required information. *

  • Related