I have a form to create new data entries for comments. Creating completely new entries works fine. However, when I have already created one entry for my entity I want to populate the data from the last entry in my form.
I have tried to modify the OnGet action to include the data from the last entry. I copied the OnGet code from the Edit view into the Create view. However, if I do this, the Create page is not displayed anymore.
I have the following model:
public class ProjectComment
{
public int Id { get; set; }
public int? ProjectId { get; set; }
public Project Project { get; set; }
public int RAGStatusId { get; set; }
public RAGStatus RAGStatus { get; set; }
public string StatusComment { get; set; }
public string EscalationComment { get; set; }
public string GeneralComment { get; set; }
public double? EOQ { get; set; }
public DateTime LastUpdateDate { get; set; }
public ProjectComment ()
{
this.LastUpdateDate = DateTime.UtcNow;
}
The create form Create.cshtml:
@page
@model SimpleProjectReporting.Pages.ClientDetails.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>ProjectComment</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ProjectComment.ProjectId" class="control-label"></label>
<select asp-for="ProjectComment.ProjectId" class="form-control" asp-items="ViewBag.ProjectId"><option value="" default="" selected="">-- Select --</option></select>
</div>
<div class="form-group">
<label asp-for="ProjectComment.RAGStatusId" class="control-label"></label>
<select asp-for="ProjectComment.RAGStatusId" class="form-control" asp-items="ViewBag.RAGStatusId"><option value="" default="" selected="">-- Select --</option></select>
</div>
<div class="form-group">
<label asp-for="ProjectComment.StatusComment" class="control-label"></label>
<input asp-for="ProjectComment.StatusComment" class="form-control" />
<span asp-validation-for="ProjectComment.StatusComment" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProjectComment.EOQ" class="control-label"></label>
<input asp-for="ProjectComment.EOQ" class="form-control" />
<span asp-validation-for="ProjectComment.EOQ" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
The original Create.cshtml.cs action:
[BindProperty]
public ProjectComment ProjectComment { get; set; }
public IActionResult OnGet()
{
ViewData["ProjectId"] = new SelectList(_context.Project.Where(a => a.IsArchived == false), "Id", "ProjectName");
ViewData["RAGStatusId"] = new SelectList(_context.RAGStatus.Where(a => a.IsActive == true), "Id", "RAGStatusName");
return Page();
}
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.ProjectComment.Add(ProjectComment);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
The modified Create.cshtml.cs OnGet action:
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
ProjectComment = await _context.ProjectComment
.Include(p => p.Project)
.Include(p => p.RAGStatus).FirstOrDefaultAsync(m => m.Id == id);
if (ProjectComment == null)
{
return NotFound();
}
When modifying the action the way I did it, the page is not displayed anymore (404 error). I would like to populate the create form with the data from the last entry in the database. If there is no comment, the create page would only populate the name of the project.
Firstly, thanks to Burak for providing the above solution, which works when you want to display the last row in the table. This helped me solving my issue by using the same approach and finding the record based on the Id of the record. I have amended the code from the Create.cshtml.cs file as follows:
public async Task<IActionResult> OnGetAsync(int? id, int projectid)
{
//This will find the "ProjectComment" object.
var projectComment = _context.ProjectComment.Find(id);
//This will display the 'ProjectComment' on the page
ProjectComment = projectComment;
if (id == null)
{
ProjectComment = projectComment;
ViewData["ProjectId"] = new SelectList(_context.Project, "Id", "ProjectName", projectid);
return Page();
}
ViewData["ProjectId"] = new SelectList(_context.Project, "Id", "ProjectName");
return Page();
}
I am using the int projectid
to populate the drop down menu of the project when there is no comment create yet.