我发现了在页面上具有多个处理程序以及相关的命名约定(即OnPostXXX)和“ asp-post- hanlder”标签帮助程序的示例。但是如何从AJAX调用中调用这些方法之一。
我有一个带有典型MVC视图和控制器的较旧示例,但这如何与Razor Page一起使用?
例如,如果我使用基本应用程序并将About.cshtml页面修改为以下内容:
@page @model AboutModel @{ ViewData["Title"] = "About"; } <h2>@ViewData["Title"]</h2> <h3>@Model.Message</h3> <input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" /> @section Scripts { <script type="text/javascript"> function ajaxTest() { console.log("Entered method"); $.ajax({ type: "POST", url: '/About', // <-- Where should this point? contentType: "application/json; charset=utf-8", dataType: "json", error: function (xhr, status, errorThrown) { var err = "Status: " + status + " " + errorThrown; console.log(err); } }).done(function (data) { console.log(data.result); }) } </script> }
并在模型页面About.cshtml.cs上
public class AboutModel : PageModel { public string Message { get; set; } public void OnGet() { Message = "Your application description page."; } public IActionResult OnPost() { //throw new Exception("stop"); return new JsonResult(""); } }
没有从Ajax调用中调用OnPost。
Razor Pages自动生成并验证防伪令牌以防止CSRF攻击。由于您没有在AJAX回调中发送任何令牌,因此请求失败。
要解决此问题,您将必须:
<form>
@Html.AntiForgeryToken
Startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN"); }
在AJAX回调中,我们添加了其他代码,以XSRF-TOKEN与请求标头一起发送。
XSRF-TOKEN
$.ajax({ type: "POST", url: '/?handler=YOUR_CUSTOM_HANDLER', // Replace YOUR_CUSTOM_HANDLER with your handler. contentType: "application/json; charset=utf-8", beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }, dataType: "json" }).done(function (data) { console.log(data.result); })
您可以通过添加来完成此操作<form>:
<form method="post"> <input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" /> </form>
或使用@Html.AntiForgeryToken:
@Html.AntiForgeryToken() <input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" />
在这两种情况下,Razor页面都会在页面加载后自动添加一个包含防伪令牌的隐藏输入字段:
<input name="__RequestVerificationToken" type="hidden" value="THE_TOKEN_VALUE" />