Search code examples
c#asp.net-coreasp.net-core-mvcasp.net-core-routing

Pass ID between 2 controllers ASP.NET Core 3.1 MVC


I'm new to programming and I need your help. I'm trying to create a simple testing application (ASP.NET Core 3.1 MVC + EF). I've created 2 models (Event, Enrollment). The goal is to open the enrollment create form page with the selected EventId by clicking on the "Enroll" button in the Events/Index page. How should I pass the EventId to the EnrollmentsController? I tried to pass EventId in the Events/Index page using a form with hidden input, but I still don't know how to handle EventId correctly in EnrollmentsController.

Note: I don't wanna use SelectList in Enrollment's Create method and view.

I will be grateful for any help. Thank you!

UPDATE: Thanks to @PanagiotisKanavos I finally get the EventId in the URL, but it still doesn't feed into the form input. There is "0". What could be wrong?

Models
public class Event
  {
    public int EventId { get; set; }

    public string Name { get; set; }

    [DataType(DataType.Date)]
    public DateTime Date { get; set; }
  }

public class Enrollment
  {
    public int EnrollmentId { get; set; }

    public int EventId { get; set; }
    public Event Event { get; set; }

    [Display(Name ="First name")]
    public string FirstName { get; set; }

    [Display(Name = "Last name")]
    public string LastName { get; set; }

    [Display(Name ="Enrollment date")]
    [DataType(DataType.DateTime)]
    public DateTime EnrollmentDate { get; set; }
  }
Events/Index view
    @model IEnumerable<FormTest.Models.Event>

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

<h1>Index</h1>

<p>
  <a asp-action="Create">Create New</a>
</p>
<table class="table">
  <thead>
    <tr>
      <th>
        @Html.DisplayNameFor(model => model.Name)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Date)
      </th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    @foreach (var item in Model)
    {
      <tr>
        <td>
          @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.Date)
        </td>
        <td>
          <a asp-action="Create" asp-controller="Enrollments" asp-route-id="@item.EventId" class="btn btn-primary">Enroll</a>
        </td>
      </tr>
    }
  </tbody>
</table>
Enrollments/Create view
@model FormTest.Models.Enrollment

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

<h1>Create</h1>

<h4>Enrollment</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="EventId" class="control-label"></label>
        <input class="form-control" asp-for="EventId" name="EventId" />
      </div>
      <div class="form-group">
        <label asp-for="FirstName" class="control-label"></label>
        <input asp-for="FirstName" class="form-control" />
        <span asp-validation-for="FirstName" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="LastName" class="control-label"></label>
        <input asp-for="LastName" class="form-control" />
        <span asp-validation-for="LastName" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="EnrollmentDate" class="control-label"></label>
        <input asp-for="EnrollmentDate" class="form-control" />
        <span asp-validation-for="EnrollmentDate" class="text-danger"></span>
      </div>
      <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
      </div>
    </form>
  </div>
</div>
EnrollmentsController Create method
// GET: Enrollments/Create
    public IActionResult Create(int eventId)
    {
      var newEnrollment = new Enrollment
      {
        EventId = eventId,
        FirstName = "John",
        LastName = "Doe",
        EnrollmentDate = DateTime.UtcNow
      };

      return View(newEnrollment);
    }

Here is the screen: enrollment/create


Solution

  • If you want to use asp-route-{value},you need to make sure the value name is consistent to the parameter name in action.Fo example,you use

    public IActionResult Create(int eventId)
    

    So that you need to use

     asp-route-eventId="@item.EventId"