在StudentService中添加Delete方法。
该方法接收一个Guid类型的参数id,并获取对应的数据。
如果数据不存在,则抛出空引用异常。
如果数据存在,则删除。
代码如下:
public void Delete(Guid id)
{
Student? student = studentRepo.Get(id);
if (student == null)
{
throw new NullReferenceException("未找到该学生,无法删除");
}
studentRepo.Delete(student);
}
在StudentController中创建Delete动作。
此动作同样接收Guid类型的参数id,并尝试调用StudentService的Delete方法。
如果没有发生异常,则return Ok("删除成功"),表示返回状态码200并附加文本信息。
如果发生异常,则return BadRequest(ex.Message),表示返回状态码400并附加错误信息文本。
代码如下:
public IActionResult Delete(Guid id)
{
try
{
studentService.Delete(id);
return Ok("删除成功");
}
catch (NullReferenceException ex)
{
return BadRequest(ex.Message);
}
}
在Index.cshtml的编辑按钮后面添加一个删除按钮,代码如下:
<td>
<a asp-action="Edit" asp-route-id="@student.Id" class="button is-warning">编辑</a>
<button class="button is-danger" onclick="Delete('@student.Id')">删除</button>
</td>
onclick="Delete('@student.Id')"表示点击此按钮会调用JavaScript的Delete函数,并将学生Id作为参数传入。
这个函数会在后面编写。
在_Layout.cshtml布局文件中,有一个语句:
@await RenderSectionAsync("Scripts", false)
现在我们在视图中添加对应的部分。
在Index.cshtml底部添加如下代码:
@section Scripts {
}
这样,其中的代码会在布局代码的@await RenderSectionAsync("Scripts", false)
部分加载。
在@section Scripts中添加Delete函数,代码如下:
function Delete(id) {
}
在Delete函数中添加sweetalert2代码实现弹窗,代码如下:
Swal.fire({
title: "是否确定删除?",
text: "此操作不可撤销!",
icon: "warning",
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否",
animation: false
});
每个配置的含义如下:
点击删除按钮后,会出现以下弹窗:
Swal.fire({
title: "是否确定删除?",
text: "此操作不可撤销!",
icon: "warning",
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否",
animation: false
}).then(result => {
if (result.isConfirmed) {
console.log("确认");
}
});
通过then可以获取result,通过result.isConfirmed可以判断点击了哪一个按钮。
如果确认,则通过fetch函数调用删除接口,代码如下:
if (result.isConfirmed) {
fetch('/Student/Delete/' + id);
}
fetch('/Student/Delete/' + id)
.then(response => {
if (response.ok) {
return response.text().then(text => {
Swal.fire({
title: text,
icon: "success"
}).then(() => location.reload());
});
}
});
如果响应的状态码为200,则response.ok为true。
这时会获取相应文本,并创建新的弹窗,显示文本。
在点击确认按钮后,还会刷新页面,这样会显示删除数据后的列表。
if (response.ok) {
return response.text().then(text => {
Swal.fire({
title: text,
icon: "success"
}).then(() => location.reload());
});
} else {
return response.text().then(text => {
Swal.fire({
title: "删除失败",
text: text,
icon: "error"
});
});
}
如果相应的状态码为400,则则response.ok为false。
同样会弹窗,并显示错误信息。
最终Delete函数的代码如下:
function Delete(id) {
Swal.fire({
title: "是否确定删除?",
text: "此操作不可撤销!",
icon: "warning",
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否",
animation: false
}).then(result => {
if (result.isConfirmed) {
fetch('/Student/Delete/' + id)
.then(response => {
if (response.ok) {
return response.text().then(text => {
Swal.fire({
title: text,
icon: "success"
}).then(() => location.reload());
});
} else {
return response.text().then(text => {
Swal.fire({
title: "删除失败",
text: text,
icon: "error"
});
});
}
});
}
});
}
可以将Delete函数封装在main.js中,这样后面的删除功能就能很轻松地调用此函数,不用重新再写一遍。
在wwwroot中创建main.js文件,并创建DeleteWithController方法。
代码如下:
function DeleteWithController(id,controller) {
Swal.fire({
title: "是否确定删除?",
text: "此操作不可撤销!",
icon: "warning",
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否",
animation: false
}).then(result => {
if (result.isConfirmed) {
fetch('/' + controller + '/Delete/' + id)
.then(response => {
if (response.ok) {
return response.text().then(text => {
Swal.fire({
title: text,
icon: "success"
}).then(() => location.reload());
});
}
else {
return response.text().then(text => {
Swal.fire({
title: "删除失败",
text: text,
icon: "error"
});
});
}
});
}
});
}
这样,之后可以通过传入控制器的名称来控制调用哪个控制器的Delete动作。
将main.js拖入布局文件的head标签中:
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link href="~/bulma/bulma.css" rel="stylesheet" />
<script src="~/sweetalert2.all.js"></script>
<script src="~/htmx.js"></script>
<script src="~/main.js"></script>
</head>
在Index.cshtml中,调用封装后的DeleteWithController函数,代码如下:
@section Scripts {
<script>
function Delete(id) {
DeleteWithController(id, 'Student');
}
</script>
}
第二个参数'Student'表示调用StudentController中的Delete动作。