Reputation: 13
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?
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);
}
Upvotes: 1
Views: 2106
Reputation: 18179
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"
Upvotes: 0
Reputation: 131492
The easiest option would be to not use a form but a link to the Enrollments controller. After all, the goal is to open the Enrollments
page, not submit the enrollment :
<td>
<a asp-controller="Enrollments"
asp-action="Create"
asp-route-id="@item.EventID">Enroll</a>
</td>
The link can be made to look like a button with the proper Bootstrap styles :
<a asp-controller="Enrollments"
asp-action="Create"
asp-route-id="@item.EventID"
class="btn btn-primary" role="button" >
Enroll
</a>
The Controller action needs to accept the id
as a parameter:
public IActionResult Create(int eventId)
{
var newEnrollment=new Enrollment{
EventId=eventId,
...
};
return View(newEnrollment);
}
The same routing tag helpers can be used in a form :
<td>
<form asp-controller="Enrollments"
asp-action="Create"
asp-route-id="@item.EventID" method="post">
<button type="submit" value="Enroll"></button>
</form>
</td>
Using a form like this is a bit weird though. This would require adding an Index(id)
action that responds to POST
along with the Index(id)
that responds to GET
.
The ASP.NET Core MVC Tutorial shows how to create an application that lists Todo items, allows editing, deleting and redirecting from the list to the edit pages.
The Tag Helpers in Forms page explains how tag helpers like asp-controller
, asp-action
and asp-route-*
can be used to specify controllers, actions and parameters in a form.
Upvotes: 1