正如某人在评论中指出的那样,Razor页面不需要控制器,就像你以前在MVC中那样。我现在也剃刀没有按钮单击事件的本机处理。为了在用户单击按钮时执行某些操作(在“隐藏代码”中),我们至少有两个选择:
我找到了许多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:
公共类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代码中的函数从未到达,并且收到Bad Request错误(400)。我错过了什么?
普通表格提交
进行常规表单提交时,根据约定,你需要处理程序方法名称以遵循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>
上面的代码将生成具有设置为url的formaction
属性的按钮标记yourBaseUrl/YourPageName?data=foo&handler=Way2
。当用户单击“提交”按钮时,它将在表单中发布此URL,因为formaction属性值将覆盖表单的默认操作URL。收到请求后,剃须刀页面框架将使用此参数(handler
)并将请求定向到相应的处理程序方法。
阿贾克斯电话
你收到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>
很好的解释!现在,我对发生的事情有了更好的了解。第一种方法就像一个魅力。我想问您关于ajax url的最后一个澄清:这里正确的语法是什么?我最初的猜测(
"@Url.Action("Way2)"
)现在导致错误500不,您需要使用
formaction
按钮的属性值,这是您需要发布到的位置(与我上面提到的url相同)。只需检查视图源。哦,对此感到抱歉。我以为那只是一个例子!无论如何,它仍然会以错误500回答。也许我的代码中还有其他错误。
500表示您的代码崩溃了。在您的断点,
OnPostWay2
看看发生了什么。成立。我
asp-page-handler
什至没有意识到即使我进行ajax调用也不必放置属性。非常感谢你。