正如有人在评论中指出的那样,Razor页面不像你以前在MVC那样需要控制器。我现在也是Razor没有按钮点击事件的原生处理。要在用户单击按钮时执行某些操作(在“代码隐藏”中),我们至少有两个选项:
我找到了很多MVC的例子,展示了如何定义Controller函数。但如上所述,我没有。
因此,我试图了解两种方式。这是我的测试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 TestModel:PageModel { private readonly 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”(提交)我能够点击按钮,但有一些缺点。默认情况下,由于帖子而重新加载页面。有时候我不需要改变任何东西,只需要调用C#函数。但我不明白如何处理多个按钮。即如果我有5个按钮,如何为每个按钮做一些不同的事情?
使用“Way2”我做错了,因为cs代码中的函数永远不会到达,我收到错误请求错误(400)。我错过了什么?
答案 0 :(得分:5)
正常表单提交
在执行普通表单提交时,按照惯例,您需要处理程序方法名称遵循On{{HttpVerb}}{{YourHanderName}}
格式
public ActionResult OnPostWay2(string data)
{
// to do : return something
}
现在确保您在form
标记内有提交按钮,并且您提到了asp-page-handler
。该属性的值应该是页面模型类(Way2
)
<form method="POST">
<button type="submit" asp-route-data="foo" asp-page-handler="Way2">Way 2</button>
</form>
以上代码将为按钮生成标记,其中formaction
attribute设置为网址yourBaseUrl/YourPageName?data=foo&handler=Way2
。
当用户点击提交按钮时,它会发布此网址的表单,因为格式属性值将覆盖表单的默认操作网址。收到请求后,剃刀页面框架将使用此参数(handler
)并将请求定向到相应的处理程序方法。
调用Ajax
您收到400(错误请求)响应,因为框架期望RequestVerificationToken
作为已发布请求数据的一部分。如果检查页面的视图源,则可以在表单中看到名为__RequestVerificationToken
的隐藏输入元素。该框架使用它来防止可能的CSRF攻击。如果您的请求没有此信息,框架将返回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调用,那么返回一个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>
答案 1 :(得分:0)
除了显示的用于处理单击的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>
答案 2 :(得分:-1)
如果您想执行任何处理程序并且只想导航到另一个页面,这是另一种简单的方法:
<button type="button" class="btn" onclick="window.location.href = '/YourPage'">Button Title</button>