ASP.NET 核心 2,在没有 MVC 的情况下使用 Razor 页面单击按钮
ASP.NET Core 2, button click with Razor pages without MVC
正如有人在评论中指出的那样,Razor 页面不需要控制器,就像您在 MVC 中习惯做的那样。我现在 Razor 也没有对按钮单击事件的本机处理。要在用户单击按钮时执行某些操作(在 "code-behind" 中),我们至少有两个选项:
- 使用提交按钮
- 使用 ajax 调用
我找到了很多 MVC 示例,它们展示了如何定义控制器函数。但是如前所述,我没有。
因此我试图理解这两种方式。这是我的测试 cshtml:
<form method="post">
<input type="submit" class="btn btn-primary" value="way1">Way 1/>
</form>
<button id="btn" type="button" class="btn btn-primary" value="way2">Way 2</button>
<script>
$(document).ready(function() {
$("#btn").click(function (e) {
e.preventDefault();
$.ajax({
url: "@Url.Action("Way2")",
type: "POST",
data: "foo",
datatype: "text",
success: function (data) {
alert(data);
}
});
return false;
});
});
</script>
这里是 cshtml.cs:
public class 测试模型:页面模型
{
私有只读 MyContext _context;
public TestModel(MyContext context)
{
_context = context;
}
public IActionResult OnPost()
{
// here I can put something to execute
// when the submit button is clicked
}
public ActionResult Way2(string data)
{
// this is never triggered
}
问题
使用 "Way1"(提交)我能够捕捉到按钮的点击,但有一些缺点。默认情况下,由于 post,页面会重新加载。有时我不需要更改任何内容,只需调用一个 C# 函数即可。但我不明白如何处理多个按钮。 IE。如果我有 5 个按钮,如何为每个按钮做不同的事情?
使用 "Way2" 我做错了什么,因为 cs 代码中的函数从未达到,我收到错误请求错误 (400)。我错过了什么?
普通表单提交
在进行普通表单提交时,按照惯例,处理程序方法名称需要遵循 On{{HttpVerb}}{{YourHanderName}}
格式
public ActionResult OnPostWay2(string data)
{
// to do : return something
}
现在确保您的提交按钮位于 form
标签内并且您提到了 asp-page-handler
。该属性的值应该是您在页面模型中的处理程序名称 class (Way2
)
<form method="POST">
<button type="submit" asp-route-data="foo" asp-page-handler="Way2">Way 2</button>
</form>
以上代码将为 formaction
attribute 设置为 url yourBaseUrl/YourPageName?data=foo&handler=Way2
的按钮生成标记。
当用户单击提交按钮时,它将 post 表单 url 因为 formaction 属性值将覆盖表单的默认操作 url。收到请求后,razor pages 框架将使用此参数 (handler
) 并将请求定向到相应的处理程序方法。
Ajax 来电
您收到 400(错误请求)响应,因为框架需要 RequestVerificationToken
作为 posted 请求数据的一部分。如果您检查页面的视图源,您可以在表单中看到一个名为 __RequestVerificationToken
的隐藏输入元素。该框架使用它来防止可能的 CSRF 攻击。如果您的请求没有此信息,框架将 return 400 错误请求。
要使您的 ajax 代码有效,您所要做的就是明确发送此代码。这是一个工作示例
$("#btn").click(function(e) {
e.preventDefault();
var t = $("input[name='__RequestVerificationToken']").val();
$.ajax({
url: $(this).attr("formaction"),
headers:
{
"RequestVerificationToken": t
},
type: "POST",
data: { data: 'foo2' },
}).done(function(data) {
console.log(data);
}).fail(function(a, v, e) {
alert(e);
});
});
现在,由于您正在进行 ajax 调用,因此 return 一个 json 响应
是有意义的
public ActionResult OnPostWay2(string data)
{
return new JsonResult("Received "+ data + " at "+DateTime.Now);
}
在上面的示例中,我们使用一些 jQuery 代码来获取名称为 __RequestVerificationToken
的输入元素并读取它的值。一种更健壮的方法是将 IAntiforgery
实现注入视图并使用 GetAndStoreTokens
方法。
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}
<script>
$(function () {
$("#btn").click(function(e) {
e.preventDefault();
var t = '@GetAntiXsrfRequestToken()';
$.ajax({
url: $(this).attr("formaction"),
headers:
{
"RequestVerificationToken": t
},
type: "POST",
data: { data: 'foo2' },
}).done(function(data) {
console.log(data);
}).fail(function(a, v, e) {
alert(e);
});
});
})
</script>
除了显示的处理点击的 jQuery 代码之外,您还必须在 asp-page-handler 中包含函数名称,以便路由到正确的函数.如果您没有 asp-page-handler,请求将在默认的 OnPost() 函数中结束。您希望它转到 OnPostWay2 函数。
代码:
<button id="btn" type="button" class="btn btn-primary" value="way2" asp-page-handler="Way2">Way 2</button>
如果您想执行任何处理程序并只想导航到另一个页面,这是另一种简单的排序方式:
<button type="button" class="btn" onclick="window.location.href = '/YourPage'">Button Title</button>
正如有人在评论中指出的那样,Razor 页面不需要控制器,就像您在 MVC 中习惯做的那样。我现在 Razor 也没有对按钮单击事件的本机处理。要在用户单击按钮时执行某些操作(在 "code-behind" 中),我们至少有两个选项:
- 使用提交按钮
- 使用 ajax 调用
我找到了很多 MVC 示例,它们展示了如何定义控制器函数。但是如前所述,我没有。
因此我试图理解这两种方式。这是我的测试 cshtml:
<form method="post">
<input type="submit" class="btn btn-primary" value="way1">Way 1/>
</form>
<button id="btn" type="button" class="btn btn-primary" value="way2">Way 2</button>
<script>
$(document).ready(function() {
$("#btn").click(function (e) {
e.preventDefault();
$.ajax({
url: "@Url.Action("Way2")",
type: "POST",
data: "foo",
datatype: "text",
success: function (data) {
alert(data);
}
});
return false;
});
});
</script>
这里是 cshtml.cs:
public class 测试模型:页面模型 { 私有只读 MyContext _context;
public TestModel(MyContext context)
{
_context = context;
}
public IActionResult OnPost()
{
// here I can put something to execute
// when the submit button is clicked
}
public ActionResult Way2(string data)
{
// this is never triggered
}
问题
使用 "Way1"(提交)我能够捕捉到按钮的点击,但有一些缺点。默认情况下,由于 post,页面会重新加载。有时我不需要更改任何内容,只需调用一个 C# 函数即可。但我不明白如何处理多个按钮。 IE。如果我有 5 个按钮,如何为每个按钮做不同的事情?
使用 "Way2" 我做错了什么,因为 cs 代码中的函数从未达到,我收到错误请求错误 (400)。我错过了什么?
普通表单提交
在进行普通表单提交时,按照惯例,处理程序方法名称需要遵循 On{{HttpVerb}}{{YourHanderName}}
格式
public ActionResult OnPostWay2(string data)
{
// to do : return something
}
现在确保您的提交按钮位于 form
标签内并且您提到了 asp-page-handler
。该属性的值应该是您在页面模型中的处理程序名称 class (Way2
)
<form method="POST">
<button type="submit" asp-route-data="foo" asp-page-handler="Way2">Way 2</button>
</form>
以上代码将为 formaction
attribute 设置为 url yourBaseUrl/YourPageName?data=foo&handler=Way2
的按钮生成标记。
当用户单击提交按钮时,它将 post 表单 url 因为 formaction 属性值将覆盖表单的默认操作 url。收到请求后,razor pages 框架将使用此参数 (handler
) 并将请求定向到相应的处理程序方法。
Ajax 来电
您收到 400(错误请求)响应,因为框架需要 RequestVerificationToken
作为 posted 请求数据的一部分。如果您检查页面的视图源,您可以在表单中看到一个名为 __RequestVerificationToken
的隐藏输入元素。该框架使用它来防止可能的 CSRF 攻击。如果您的请求没有此信息,框架将 return 400 错误请求。
要使您的 ajax 代码有效,您所要做的就是明确发送此代码。这是一个工作示例
$("#btn").click(function(e) {
e.preventDefault();
var t = $("input[name='__RequestVerificationToken']").val();
$.ajax({
url: $(this).attr("formaction"),
headers:
{
"RequestVerificationToken": t
},
type: "POST",
data: { data: 'foo2' },
}).done(function(data) {
console.log(data);
}).fail(function(a, v, e) {
alert(e);
});
});
现在,由于您正在进行 ajax 调用,因此 return 一个 json 响应
是有意义的public ActionResult OnPostWay2(string data)
{
return new JsonResult("Received "+ data + " at "+DateTime.Now);
}
在上面的示例中,我们使用一些 jQuery 代码来获取名称为 __RequestVerificationToken
的输入元素并读取它的值。一种更健壮的方法是将 IAntiforgery
实现注入视图并使用 GetAndStoreTokens
方法。
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}
<script>
$(function () {
$("#btn").click(function(e) {
e.preventDefault();
var t = '@GetAntiXsrfRequestToken()';
$.ajax({
url: $(this).attr("formaction"),
headers:
{
"RequestVerificationToken": t
},
type: "POST",
data: { data: 'foo2' },
}).done(function(data) {
console.log(data);
}).fail(function(a, v, e) {
alert(e);
});
});
})
</script>
除了显示的处理点击的 jQuery 代码之外,您还必须在 asp-page-handler 中包含函数名称,以便路由到正确的函数.如果您没有 asp-page-handler,请求将在默认的 OnPost() 函数中结束。您希望它转到 OnPostWay2 函数。
代码:
<button id="btn" type="button" class="btn btn-primary" value="way2" asp-page-handler="Way2">Way 2</button>
如果您想执行任何处理程序并只想导航到另一个页面,这是另一种简单的排序方式:
<button type="button" class="btn" onclick="window.location.href = '/YourPage'">Button Title</button>