I'm currently learning RazorPages in codeacademy.com. I did everything that was shown in the video Tutorial, and unfortunately is doesn't work:
The task for the project: "Data Delete The current project has a button on the Index page list that deletes the current Continent or Country. The button will be modified to call a discrete Delete.cshtml page. This page will display the current record for review and provide a Delete button. Once the deletion occurs, the user is redirected back to the list so they get visual feedback of a successful task.
The code and markup are easily copied from the existing Detail.cshtml page. After copying that page, we add a delete button and copy the necessary statements from the OnPostAsync() method in the Index.cshtml.cs page." The Delete page was created. The problem is: When I press button Delete on the Delete page I have redirection to this link in browser:
https://localhost/Continents/Delete/SA?Continent.ID=SA
Actually no Delete happends No redirection
What mistakes maybe here?
The code Delete.cshtml:
@page "{id}"
@model DeleteModel
@{
ViewData["Title"] = "Continent Delete";
}
<div >
<div >
<h1 >
Continent Delete
</h1>
<a asp-page="./Index">
Back to List
</a>
</div>
</div>
[enter image description here](https://i.stack.imgur.com/tFnrX.jpg)
<div >
<div style="flex:0 0 15%">
@Html.DisplayNameFor(model => model.Continent.ID)
</div>
<div style="flex:1 0 auto">
@Html.DisplayFor(model => model.Continent.ID)
</div>
</div>
<div >
<div style="flex:0 0 15%">
@Html.DisplayNameFor(model => model.Continent.Name)
</div>
<div style="flex:1 0 auto">
@Html.DisplayFor(model => model.Continent.Name)
</div>
</div>
<form metod="post" >
<input type="hidden" asp-for="Continent.ID"/>
<input type="submit" value="Delete" />
</form>
Delete.cshtml.cs:
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorCountry.Models;
using RazorCountry.Data;
namespace RazorCountry.Pages.Continents
{
public class DeleteModel : PageModel
{
private readonly CountryContext _context;
public DeleteModel(CountryContext context)
{
_context = context;
}
public Continent Continent { get; set; }
public async Task<IActionResult> OnGetAsync(string id)
{
Continent = await _context.Continents
.Include(c => c.Countries)
.AsNoTracking()
.FirstOrDefaultAsync(m => m.ID == id);
if (Continent == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string id)
{
if (id == null)
{
return NotFound();
}
// Find the continent
Continent Continent = await _context.Continents.FindAsync(id);
//Delete the continent
if (Continent != null)
{
_context.Continents.Remove(Continent);
}
//Persist Changes
await _context.SaveChangesAsync();
//Redirect to the user
return RedirectToPage("./Index");
}
}
}
Model Continent.cs:
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
namespace RazorCountry.Models
{
public class Continent
{
[Required, StringLength(2, MinimumLength = 2), Display(Name = "Code")]
[RegularExpression(@"[A-Z] ", ErrorMessage = "Only upper case characters are allowed.")]
public string ID { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Country> Countries { get; set; }
}
}
Try to understand how RazorPages functional works, try to fix mistake in a correct way
CodePudding user response:
The reason that no error occurs is because your OnPostAsync
method is not being hit. You have mis-spelled the method
attribute in your form (you have metod
) so submitting it generates the default GET
request and your OnGetAsync
handler is executed instead.
Once you have corrected that error, you still have an unresolved issue.
Your OnPostAsync
handler expects a parameter named id
. The hidden field tag helper in your form generates a parameter with a name of Continent.ID
. Consequently the value will not be bound to the id
parameter. The simplest solution is to do away with the tag helper in the form a the bottom of your Delete page and replace it with a plain HTML input with a name
attribute:
<form method="post" >
<input type="hidden" name="id" value="@Continent.ID"/>
<input type="submit" value="Delete" />
</form>
You can read more about model binding in general here: https://www.learnrazorpages.com/razor-pages/model-binding
CodePudding user response:
Thanks to @MikeBrind finally, I changed the code
<form method="post" >
<input type="hidden" name="id" value="@Model.Continent.ID"/>
<input type="submit" value="Delete" />
</form>
And it works!