示例AJAX回调到ASP.NET Core Razor页面

时间:2017-09-25 17:16:33

标签: c# ajax asp.net-core-2.0 razor-pages

我发现在页面上有多个处理程序的示例以及相关的命名约定(即OnPostXXX)和'asp-post-hanlder'标记帮助程序。但是如何从AJAX调用中调用这些方法之一。

我有一个较旧的示例,其中包含典型的MVC视图和控制器,但这如何与Razor页面一起使用?

例如,如果我使用基本应用程序并将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。

7 个答案:

答案 0 :(得分:9)

需要添加AntiForgery令牌,页面上需要有一个表单元素。

在你的Startup.Cs中 在services.AddMvc()

之前添加
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

然后在你的ajax中,改为:

 $.ajax({
            type: "POST",
            url: '/About', // <-- Where should this point?
            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);
        })

    }

然后在你的方法中添加

  [ValidateAntiForgeryToken]
    public IActionResult OnPost()
    {
        //throw new Exception("stop");
        return new JsonResult ("Hello Response Back");
    }

在cshtml页面上,在表单中包装按钮,否则不会添加AntiForgery cookie。

<form method="post">
    <input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" />
</form>

答案 1 :(得分:1)

请参阅文档的相关部分 https://docs.microsoft.com/en-us/aspnet/core/mvc/razor-pages/?tabs=visual-studio

  

页面的URL路径关联由页面在文件系统中的位置决定。下表显示了Razor页面路径和匹配的URL

/Pages/Index.cshtml映射到/或/索引

/Pages/Contact.cshtml映射到/ Contact

答案 2 :(得分:0)

一切运作良好,但必须做出一些改变:

1)打开Startup.cs:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
            services.AddMvc();
        }

2)打开HomeController.cs:

[ValidateAntiForgeryToken]
        public IActionResult OnPost()
        {
            return new JsonResult("Hello Response Back");
        }

3)打开About.cshtml:

@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>

<p>Use this area to provide additional information.</p>
<form method="post">
    <input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" />
</form>

<script src="~/lib/jquery/dist/jquery.js"></script>

<script type="text/javascript">
    function ajaxTest() {
        $.ajax({
            type: "POST",
            url: 'onPost',
            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);
        })
    }
</script>

应该注意的是&#34; onPost&#34;被添加到控制器内部,所以在AJAX中正确的&#34; url&#34;应该表明。然后:

url: 'onPost',

答案 3 :(得分:0)

答案对我有用。我只想补充一点,如果我们在页面上有自定义方法,如:

   public IActionResult OnPostFilter1()
    {
        return new JsonResult("Hello Response Back");
    }

然后我们应该在url中指定处理程序名称:

url: 'OnPost?handler=filter1',

答案 4 :(得分:0)

在查看上面的答案后,我使用Visual Studio 2017 Preview 2获得了JSON ajax以使用.NET Core 2.1 Razor页面:

<强> Startup.cs

services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

<强> PostJson.cshtml

@page
@model myProj.Pages.PostJsonModel
@{
    ViewData["Title"] = "PostJson";
}

<input type="button" value="Post Json" class="btn btn-default" onclick="postJson();" />

<script>
    function ajaxRazorPostJson(o) {
        return $.ajax({
            type: "POST",
            data: JSON.stringify(o),
            url: 'postJson',
            contentType: "application/json; charset=utf-8",
            beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); },
            dataType: "json"
        });
    }

    function postJson() {
        ajaxRazorPostJson({ reqKey: "reqVal" }).done(data => alert(data));
    }
</script>

<强> PostJson.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json.Linq;    

namespace myProj.Pages
{
    public class PostJsonModel : PageModel
    {
        public IActionResult OnPost([FromBody] JObject jobject)
        {
            // request buffer in jobject
            return new ContentResult { Content = "{ \"resKey\": \"resVal\" }", ContentType = "application/json" };
            // or ie return new JsonResult(obj);
        }
    }
}

<强>浏览器

http://localhost:44322/postJson

答案 5 :(得分:0)

可接受的解决方案在本地开发机器上工作,但是失败了,然后部署在Nginx反向代理后面的Debian服务器中(未发现404错误)。

这是有效载荷数据的有效示例:

<script type="text/javascript">
    $('#btnPost').on('click', function () {

        var payloadData; /*asign payload data here */

        $.post({              /* method name in code behind, and full path to my view*/
            url: '@Url.Action("OnPostAsync", "/Turtas/Inventorius/InventoriausValdymas")', 
            beforeSend: function (xhr) {
                xhr.setRequestHeader("XSRF-TOKEN",
                    $('input:hidden[name="__RequestVerificationToken"]').val());
            },
            data: JSON.stringify({ payloadData }),
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        })
    })
</script>

VS 2017; .Net Core 2.2 Razor页面; jQuery 3.3.1

答案 6 :(得分:-1)

以下使用 headers 设置在ASP.NET Core MVC 3.1中工作:

$.ajax({
    type: "POST",
    url: '/Controller/Action', 
    data: {
        id: 'value'
    },
    headers: {
        RequestVerificationToken:
            $('input:hidden[name="__RequestVerificationToken"]').val()
    },
    error: function (xhr, status, errorThrown) {
        var err = "Error: " + status + " " + errorThrown;
        console.log(err);
    }
}).done(function (data) {
    console.log(data.result);
});

在控制器方法上包括 ValidateAntiForgeryToken 属性:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<JsonResult> Action(string id)
    {
        var result = $"You sent '{id}'";
        return Json(new { id, result });
    }