Razor 应用程序:我希望 html 按钮显示 jQuery UI 在执行 C# 方法删除数据库注册表之前确认对话框
Razor app: I want html button shows jQuery UI confirm dialog before execute C# method to delete DB registry
我正在使用 Razor 应用学习网络开发。我有一个页面,PeopleIndex,其中 table 显示人员列表,在每一行之后,第一个 用于编辑人员数据,第二个 从我想的地方喜欢调用 jQuery UI 确认对话框(我已经在 .cshtml 中有代码),如果我单击“是”按钮,应该删除该人员注册表,这就是调用.cshtml.cs 文件中的 Delete() 方法。我明确表示此过程不是提交操作,我之所以这样说是因为我在 Internet 上找到的与我的问题相关的所有内容都是关于“form method = POST and type=submit”,并且所有这些都应该完成在另一个页面中,我只想在我的个人列表页面中执行此操作。但是,如果我错了,我会听取意见。
我附上我的 PeopleIndex Razor 页面的两个文件:
*************** PeopleIndex.cshtml *****************
@page
@model WebAppPersonas.Pages.PersonasIndexModel
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head title="Lista de personas">
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: auto,
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Si')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
call Delete() C# method from .cs file // neither know what goes here
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('#deleteReg').click(function (e) {
e.preventDefault();
$('#confirmDialog').dialog('open');
});
});
</script>
</head>
<body>
<a asp-page="./InsertUpdate" class="btn btn-primary"> Add person </a>
<h2> People LIst </h2>
<table class="table">
<thead>
<tr>
<th> @Html.DisplayNameFor(Model => Model.people[0].Id) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Name) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Age) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Email) </th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.people)
{
<tr>
<td> @Html.DisplayFor(modelItem => item.Id) </td>
<td> @Html.DisplayFor(modelItem => item.Name) </td>
<td> @Html.DisplayFor(modelItem => item.Age) </td>
<td> @Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="@item.Id"> Update </a> | <input type="button" value="Delete" onclick="I don't know what goes here"/> </td>
</tr>
}
</tbody>
</table>
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry ¿Are you sure?</p>
</div>
</body>
</html>
********** PeopleIndex.cshtml.cs *****************
public void OnGet()
{
people = dataAccess.GetPeople();
}
public ActionResult Delete(int? id)
{
dataAccess.DeletePerson(id.Value);
return Redirect("./PeopleIndex");
}
我不得不切断 .cshtml.cs 文件的 header,因为该网站不允许我格式化该代码,因此该网站不允许我这样做post问题。我希望现在它允许我 post 这个问题。这很复杂。我认为用不同语言格式化代码的职责应该更容易,但是,...这就是...
提前谢谢你。
编辑***
嗨,迈克尔
我用你给我的代码编辑了文件。但是我在:
中设置了一个断点
$('.deleteButton').click(function (e) {
e.preventDefault();
const id = $(e.target).data("id");
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
它不会输入来自此处按钮的代码:
<tbody>
@foreach (var item in Model.people)
{
<tr>
<td> @Html.DisplayFor(modelItem => item.Id) </td>
<td> @Html.DisplayFor(modelItem => item.Name) </td>
<td> @Html.DisplayFor(modelItem => item.Age) </td>
<td> @Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="@item.Id"> Update </a> | <button class="deleteButton" data-id="@item.Id"> Delete </button> </td>
</tr>
}
</tbody>
所以它现在不工作,但至少我们现在知道问题出在哪里了。
我再次附加受影响的文件和当前更新,我没有放 .cs 因为这是唯一可以的。
1、.cshtml.cs(现在我们知道点击deleteButton并没有进入JS函数,我试过改class for name但是还是一样。)
@page
@model WebAppPersonas.Pages.PeopleIndexModel
@section Head
{
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
@*<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>*@
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: auto,
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Yes')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
DeletePerson($(this).data("id"));
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('.deleteButton').click(function (e) {
e.preventDefault();
const id = $(e.target).data("id");
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
});
</script>
<script>
const token = document.getElementsByName('__RequestVerificationToken')[0].nodeValue;
function DeletePerson(id) {
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.then(result => { window.location.reload(); })
.catch(error => alert("Error sending DELETE request."))
}
</script>
}
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry. Are you sure? </p>
</div>
<a asp-page="./InsertUpdate" class="btn btn-primary"> Add person </a>
<h2> List of People </h2>
<table class="table">
<thead>
<tr>
<th> @Html.DisplayNameFor(Model => Model.people[0].Id) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Name) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Age) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Email) </th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.people)
{
<tr>
<td> @Html.DisplayFor(modelItem => item.Id) </td>
<td> @Html.DisplayFor(modelItem => item.Name) </td>
<td> @Html.DisplayFor(modelItem => item.Age) </td>
<td> @Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="@item.Id"> Update </a> | <button class="deleteButton" data-id="@item.Id"> Delete </button> </td>
</tr>
}
</tbody>
</table>
@Html.AntiForgeryToken()
2、_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebAppPersonas</title>
@*<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />*@
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
@*<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>*@
@RenderSection("Head", false)
</head>
<body>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">WebAppPersonas</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - WebAppPersonas - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
@*<script src="~/lib/jquery/dist/jquery.min.js"></script>*@
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Blockquote
Razor 页面是一种服务器端技术。您不能在 javascript 中调用 C# 函数。反而
你可以提出要求。此请求将分配给您的 Razor 页面中的方法,使用
路由中间件。
为了说明这意味着我们有一个简单的 PageModel 的问题:
public class Person
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
}
public class PersonsModel : PageModel
{
private static List<Person> _persons = new List<Person>
{
new Person{Id = 1, Firstname = "FN1", Lastname = "LN1"},
new Person{Id = 2, Firstname = "FN2", Lastname = "LN2"},
new Person{Id = 3, Firstname = "FN3", Lastname = "LN3"},
new Person{Id = 4, Firstname = "FN4", Lastname = "LN4"}
};
public List<Person> Persons => _persons;
public void OnGet()
{
}
// Called from fetch (JavaScript)
public IActionResult OnDelete(int id)
{
var person = _persons.Find(p => p.Id == id);
if (person == null) { return NotFound(); // HTTP 404 triggers .catch() in fetch }
_persons.Remove(person);
return new NoContentResult(); // HTTP 204
}
}
如您所见,OnDelete returns 没有重定向,因为服务器响应没有被解释
浏览器。是否回应此 return 值取决于您。
在我们的 Razor 视图中,我们有一个人员列表和每个人的删除按钮。
@page
@model RazorDemo.Pages.PersonsModel
@{
}
<ul>
@foreach (var p in Model.Persons)
{
<li>@p.Id - @p.Firstname @p.Lastname <button onclick="deletePerson(@p.Id)">Delete</button></li>
}
</ul>
@*Generate a hidden field with the RequestVerificationToken.*@
@Html.AntiForgeryToken()
<script>
const token = document.getElementsByName('__RequestVerificationToken')[0].value;
// Send a DELETE request as multipart/form-data (an ordinary HTML form)
function deletePerson(id) {
// Crates a HTML form with one parameter (id)
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.catch(error => alert("Error sending DELETE request."));
}
</script>
服务器生成的 HTML 表单包含带有防伪标记的隐藏输入元素
(请求验证令牌,更多信息请见 www.learnrazorpages.com)。
我们必须使用 @Html.AntiForgeryToken().
手动创建此元素
JavaScript得到这个token的值。之后我们创建一个普通的有效负载
HTML 表单,因为我们想在服务器端使用标准模型绑定和验证。
现在我们需要做一些配置,因为我们要在
请求 header.
public void ConfigureServices(IServiceCollection services)
{
// Other services
services.AddAntiforgery(o => o.HeaderName = "xsrf-token");
}
现在你可以删除一个人,但是你的UI不会刷新。仅在重新加载后删除
人消失。现在你到了需要 JavaScript MVVM 框架而不是 JQuery 的地步。
一个小JavaScript框架是Knockout。一个 JavaScript MVVM 框架
根据来自您服务器的 json 值生成 html 内容。您可以发送您的人员名单
作为 JSON 发送给客户端并将其存储在数组中。当你删除一个人时,你
可以删除该数组中的那个人,模板引擎将自动更新您的视图。
Razor 页面支持 JSON 结果和不同的处理程序,因此您不需要单独的控制器。
// GET Persons?handler=AllPersons
public IActionResult OnGetAllPersons()
{
return new JsonResult(Persons);
}
使用jQueryUI
要包含 jQuery UI 引用,您可以在主布局中定义一个部分 (_Layout.cshtml)。
默认模板使用 bootstrap 和 jQuery。要使 jQuery UI 正常工作,您必须参考
jQuery jQuery UI 附带的捆绑版本。我们还在head元素中定义了一个section,可以被
剃刀页面。
_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Other references (bootstrap css, ...) -->
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
@RenderSection("Head", false)
</head>
<body>
<!-- Your layout with RenderBody() -->
<!-- NO REFERENCE TO JQUERY! -->
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
重要提示:删除(或注释掉)末尾对 lib/jquery/dist/jquery.min.js 的引用
body.
现在我们可以向“人员”页面添加一个对话框:
@page
@model RazorDemo.Pages.PersonsModel
@section Head
{
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: "auto",
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Si')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
// Call deletePerson with data-id of the dialog div.
deletePerson($(this).data("id"));
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('.deleteButton').click(function (e) {
e.preventDefault();
// We have a generic event handler for all buttons.
// So we have to look at the event source and read the data-id attribute.
const id = $(e.target).data("id");
// Now we create a data attribute for <div id="confirmDialog">
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
});
function deletePerson(id) {
const token = document.getElementsByName('__RequestVerificationToken')[0].value;
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.then(result => { window.location.reload(); }) // Reloading the page. This is not AJAX, but it will do the job.
.catch(error => alert("Error sending DELETE request."));
}
</script>
}
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry. Are you sure?</p>
</div>
<ul>
@foreach (var p in Model.Persons)
{
<li>@p.Id - @p.Firstname @p.Lastname <button class="deleteButton" data-id="@p.Id">Delete</button></li>
}
</ul>
@*Generate a hidden field with the RequestVerificationToken.*@
@Html.AntiForgeryToken()
您可以使用通用事件处理程序(用 .click() 在 jQuery 中定义)而不是 onClick。
因此,按钮具有 data-id 属性。在事件处理程序中,我们检索此 id
使用 $(e.target).data("id") 并将 data-id 属性动态分配给对话框 div.
我正在使用 Razor 应用学习网络开发。我有一个页面,PeopleIndex,其中 table 显示人员列表,在每一行之后,第一个 用于编辑人员数据,第二个 从我想的地方喜欢调用 jQuery UI 确认对话框(我已经在 .cshtml 中有代码),如果我单击“是”按钮,应该删除该人员注册表,这就是调用.cshtml.cs 文件中的 Delete() 方法。我明确表示此过程不是提交操作,我之所以这样说是因为我在 Internet 上找到的与我的问题相关的所有内容都是关于“form method = POST and type=submit”,并且所有这些都应该完成在另一个页面中,我只想在我的个人列表页面中执行此操作。但是,如果我错了,我会听取意见。 我附上我的 PeopleIndex Razor 页面的两个文件:
*************** PeopleIndex.cshtml *****************
@page
@model WebAppPersonas.Pages.PersonasIndexModel
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head title="Lista de personas">
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: auto,
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Si')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
call Delete() C# method from .cs file // neither know what goes here
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('#deleteReg').click(function (e) {
e.preventDefault();
$('#confirmDialog').dialog('open');
});
});
</script>
</head>
<body>
<a asp-page="./InsertUpdate" class="btn btn-primary"> Add person </a>
<h2> People LIst </h2>
<table class="table">
<thead>
<tr>
<th> @Html.DisplayNameFor(Model => Model.people[0].Id) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Name) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Age) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Email) </th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.people)
{
<tr>
<td> @Html.DisplayFor(modelItem => item.Id) </td>
<td> @Html.DisplayFor(modelItem => item.Name) </td>
<td> @Html.DisplayFor(modelItem => item.Age) </td>
<td> @Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="@item.Id"> Update </a> | <input type="button" value="Delete" onclick="I don't know what goes here"/> </td>
</tr>
}
</tbody>
</table>
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry ¿Are you sure?</p>
</div>
</body>
</html>
********** PeopleIndex.cshtml.cs *****************
public void OnGet()
{
people = dataAccess.GetPeople();
}
public ActionResult Delete(int? id)
{
dataAccess.DeletePerson(id.Value);
return Redirect("./PeopleIndex");
}
我不得不切断 .cshtml.cs 文件的 header,因为该网站不允许我格式化该代码,因此该网站不允许我这样做post问题。我希望现在它允许我 post 这个问题。这很复杂。我认为用不同语言格式化代码的职责应该更容易,但是,...这就是... 提前谢谢你。
编辑*** 嗨,迈克尔 我用你给我的代码编辑了文件。但是我在:
中设置了一个断点 $('.deleteButton').click(function (e) {
e.preventDefault();
const id = $(e.target).data("id");
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
它不会输入来自此处按钮的代码:
<tbody>
@foreach (var item in Model.people)
{
<tr>
<td> @Html.DisplayFor(modelItem => item.Id) </td>
<td> @Html.DisplayFor(modelItem => item.Name) </td>
<td> @Html.DisplayFor(modelItem => item.Age) </td>
<td> @Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="@item.Id"> Update </a> | <button class="deleteButton" data-id="@item.Id"> Delete </button> </td>
</tr>
}
</tbody>
所以它现在不工作,但至少我们现在知道问题出在哪里了。 我再次附加受影响的文件和当前更新,我没有放 .cs 因为这是唯一可以的。 1、.cshtml.cs(现在我们知道点击deleteButton并没有进入JS函数,我试过改class for name但是还是一样。)
@page
@model WebAppPersonas.Pages.PeopleIndexModel
@section Head
{
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
@*<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>*@
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: auto,
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Yes')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
DeletePerson($(this).data("id"));
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('.deleteButton').click(function (e) {
e.preventDefault();
const id = $(e.target).data("id");
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
});
</script>
<script>
const token = document.getElementsByName('__RequestVerificationToken')[0].nodeValue;
function DeletePerson(id) {
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.then(result => { window.location.reload(); })
.catch(error => alert("Error sending DELETE request."))
}
</script>
}
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry. Are you sure? </p>
</div>
<a asp-page="./InsertUpdate" class="btn btn-primary"> Add person </a>
<h2> List of People </h2>
<table class="table">
<thead>
<tr>
<th> @Html.DisplayNameFor(Model => Model.people[0].Id) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Name) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Age) </th>
<th> @Html.DisplayNameFor(Model => Model.people[0].Email) </th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.people)
{
<tr>
<td> @Html.DisplayFor(modelItem => item.Id) </td>
<td> @Html.DisplayFor(modelItem => item.Name) </td>
<td> @Html.DisplayFor(modelItem => item.Age) </td>
<td> @Html.DisplayFor(modelItem => item.Email) </td>
<td> <a asp-page="./InsertUpdate" asp-route-id="@item.Id"> Update </a> | <button class="deleteButton" data-id="@item.Id"> Delete </button> </td>
</tr>
}
</tbody>
</table>
@Html.AntiForgeryToken()
2、_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebAppPersonas</title>
@*<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />*@
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
@*<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>*@
@RenderSection("Head", false)
</head>
<body>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">WebAppPersonas</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - WebAppPersonas - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
@*<script src="~/lib/jquery/dist/jquery.min.js"></script>*@
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Blockquote
Razor 页面是一种服务器端技术。您不能在 javascript 中调用 C# 函数。反而 你可以提出要求。此请求将分配给您的 Razor 页面中的方法,使用 路由中间件。
为了说明这意味着我们有一个简单的 PageModel 的问题:
public class Person
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
}
public class PersonsModel : PageModel
{
private static List<Person> _persons = new List<Person>
{
new Person{Id = 1, Firstname = "FN1", Lastname = "LN1"},
new Person{Id = 2, Firstname = "FN2", Lastname = "LN2"},
new Person{Id = 3, Firstname = "FN3", Lastname = "LN3"},
new Person{Id = 4, Firstname = "FN4", Lastname = "LN4"}
};
public List<Person> Persons => _persons;
public void OnGet()
{
}
// Called from fetch (JavaScript)
public IActionResult OnDelete(int id)
{
var person = _persons.Find(p => p.Id == id);
if (person == null) { return NotFound(); // HTTP 404 triggers .catch() in fetch }
_persons.Remove(person);
return new NoContentResult(); // HTTP 204
}
}
如您所见,OnDelete returns 没有重定向,因为服务器响应没有被解释 浏览器。是否回应此 return 值取决于您。
在我们的 Razor 视图中,我们有一个人员列表和每个人的删除按钮。
@page
@model RazorDemo.Pages.PersonsModel
@{
}
<ul>
@foreach (var p in Model.Persons)
{
<li>@p.Id - @p.Firstname @p.Lastname <button onclick="deletePerson(@p.Id)">Delete</button></li>
}
</ul>
@*Generate a hidden field with the RequestVerificationToken.*@
@Html.AntiForgeryToken()
<script>
const token = document.getElementsByName('__RequestVerificationToken')[0].value;
// Send a DELETE request as multipart/form-data (an ordinary HTML form)
function deletePerson(id) {
// Crates a HTML form with one parameter (id)
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.catch(error => alert("Error sending DELETE request."));
}
</script>
服务器生成的 HTML 表单包含带有防伪标记的隐藏输入元素 (请求验证令牌,更多信息请见 www.learnrazorpages.com)。 我们必须使用 @Html.AntiForgeryToken().
手动创建此元素JavaScript得到这个token的值。之后我们创建一个普通的有效负载 HTML 表单,因为我们想在服务器端使用标准模型绑定和验证。
现在我们需要做一些配置,因为我们要在 请求 header.
public void ConfigureServices(IServiceCollection services)
{
// Other services
services.AddAntiforgery(o => o.HeaderName = "xsrf-token");
}
现在你可以删除一个人,但是你的UI不会刷新。仅在重新加载后删除 人消失。现在你到了需要 JavaScript MVVM 框架而不是 JQuery 的地步。 一个小JavaScript框架是Knockout。一个 JavaScript MVVM 框架 根据来自您服务器的 json 值生成 html 内容。您可以发送您的人员名单 作为 JSON 发送给客户端并将其存储在数组中。当你删除一个人时,你 可以删除该数组中的那个人,模板引擎将自动更新您的视图。
Razor 页面支持 JSON 结果和不同的处理程序,因此您不需要单独的控制器。
// GET Persons?handler=AllPersons
public IActionResult OnGetAllPersons()
{
return new JsonResult(Persons);
}
使用jQueryUI
要包含 jQuery UI 引用,您可以在主布局中定义一个部分 (_Layout.cshtml)。 默认模板使用 bootstrap 和 jQuery。要使 jQuery UI 正常工作,您必须参考 jQuery jQuery UI 附带的捆绑版本。我们还在head元素中定义了一个section,可以被 剃刀页面。
_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Other references (bootstrap css, ...) -->
<script src="~/lib/jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
@RenderSection("Head", false)
</head>
<body>
<!-- Your layout with RenderBody() -->
<!-- NO REFERENCE TO JQUERY! -->
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
重要提示:删除(或注释掉)末尾对 lib/jquery/dist/jquery.min.js 的引用 body.
现在我们可以向“人员”页面添加一个对话框:
@page
@model RazorDemo.Pages.PersonsModel
@section Head
{
<link rel="stylesheet" href="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.css" />
<script src="~/lib/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
// Confirmation Dialog
$('#confirmDialog').dialog({
autoOpen: false,
width: 500,
height: "auto",
modal: true,
resizable: false,
buttons: {
"Yes": function () {
$(".ui-dialog-buttonpane button:contains('Si')").button("disable");
$(".ui-dialog-buttonpane button:contains('No')").button("disable");
// Call deletePerson with data-id of the dialog div.
deletePerson($(this).data("id"));
$(this).dialog("close");
},
"No": function () {
$(this).dialog("close");
}
}
});
$('.deleteButton').click(function (e) {
e.preventDefault();
// We have a generic event handler for all buttons.
// So we have to look at the event source and read the data-id attribute.
const id = $(e.target).data("id");
// Now we create a data attribute for <div id="confirmDialog">
$('#confirmDialog').data("id", id);
$('#confirmDialog').dialog('open');
});
});
function deletePerson(id) {
const token = document.getElementsByName('__RequestVerificationToken')[0].value;
const formData = new FormData();
formData.append("id", id);
fetch(window.location.href, {
method: 'DELETE',
headers: { 'XSRF-TOKEN': token },
body: formData
})
.then(result => { window.location.reload(); }) // Reloading the page. This is not AJAX, but it will do the job.
.catch(error => alert("Error sending DELETE request."));
}
</script>
}
<div id="confirmDialog" title="Confirm delete">
<p> You are about to delete a registry. Are you sure?</p>
</div>
<ul>
@foreach (var p in Model.Persons)
{
<li>@p.Id - @p.Firstname @p.Lastname <button class="deleteButton" data-id="@p.Id">Delete</button></li>
}
</ul>
@*Generate a hidden field with the RequestVerificationToken.*@
@Html.AntiForgeryToken()
您可以使用通用事件处理程序(用 .click() 在 jQuery 中定义)而不是 onClick。 因此,按钮具有 data-id 属性。在事件处理程序中,我们检索此 id 使用 $(e.target).data("id") 并将 data-id 属性动态分配给对话框 div.