I'm trying to get a delete operation to work on an entity with a composite key on a Razor page using ASP.NET Core 3.0 and Entity Framework 6. The entity in question is a CourseAssignment
whose composite key is composed of an InstructorID
value and a CourseID
value.
For an entity with an ordinary, single-field key—say, a Course
entity with a CourseID
primary key—the code on the razor page is this:
<form method="post">
<input type="hidden" asp-for="Course.CourseID" />
<input type="submit" value="Delete" class="btn btn-danger" /> |
<a asp-page="./Index">Back to List</a>
</form>
Which produces a URL like this: https://localhost:44388/Courses/Delete?id=1045
The C# code that acts on this is:
public async Task<IActionResult> OnPostAsync(int? id) {
if (id == null) {
return NotFound();
}
Course = await _context.Courses.FindAsync(id);
if (Course != null) {
_context.Courses.Remove(Course);
await _context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
How do I change both the razor page and the C# OnPostAsync
action to handle the entity with a composite key requiring two values?
Thanks!
Update your HTML form to something like the following:
<form method="post">
<input type="hidden" asp-for="Course.CourseID" />
<input type="hidden" asp-for="Course.InstructorID" />
<input type="submit" value="Delete" class="btn btn-danger" /> |
<a asp-page="./Index">Back to List</a>
</form>
Create a new class for handling the composite key. You can use your existing view model class too.
public class DeleteCourseRequest {
public int CourseId { get; set; }
public int InstructorId { get; set; }
}
Then update your controller's OnPostAsync action to something like this:
public async Task<IActionResult> OnPostAsync(DeleteCourseRequest request) {
if (request == null) {
return NotFound();
}
Course = await _context.Courses.FirstOrDefaultAsync(c => c.CourseID == request.CourseID && c.InstructorID == request.InstructorID);
if (Course != null) {
_context.Courses.Remove(Course);
await _context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
The issue is that when doing a Post with more than one parameter, you would either have to use [FromBody]
or [FromUri]
bindings on your parameters. This tells ASP.NET Web API where to parse the parameters. Another option is to use a view model to pass your information from your form to your controller.