Example AJAX call back to an ASP.NET Core Razor Page

时光毁灭记忆、已成空白 提交于 2019-11-26 04:26:55

问题


I\'ve found examples of have multiple handlers on a page and the associated naming convention (ie OnPostXXX) and \'asp-post-hanlder\' tag helper. But how can I call one of these methods from an AJAX call.

I have an older example with a typical MVC view and controller but how does this work with a Razor Page?

For example if I take the base application and modify the About.cshtml page to the following:

@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>
}

And on the model page 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(\"\");
    }
}

The OnPost is not called from the Ajax call.


回答1:


The AntiForgery Token needs to be added and there needs to be a form element on the page.

in your Startup.Cs Add this before services.AddMvc()

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

thenn in your ajax, change to:

 $.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);
        })

    }

then in your method add

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

On the cshtml page wrap the button in a form or no AntiForgery cookie will be added.

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



回答2:


Please see this related section of the documentation https://docs.microsoft.com/en-us/aspnet/core/mvc/razor-pages/?tabs=visual-studio

The associations of URL paths to pages are determined by the page's location in the file system. The following table shows a Razor Page path and the matching URL

/Pages/Index.cshtml maps to / or /Index

/Pages/Contact.cshtml maps to /Contact




回答3:


Everything works well, but some changes have to be made:

1)Open Startup.cs:

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

2)Open HomeController.cs:

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

3)Open 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>

It should be noted that "onPost" was added inside the controller, so in AJAX the correct "url" should be indicated. Then:

url: 'onPost',



回答4:


The answer works for me. I would only add that if we have customized methods on the page like:

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

Then we should specify the handler name in the url:

url: 'OnPost?handler=filter1',



回答5:


After looking at the answers above I got JSON ajax to work with .NET Core 2.1 Razor pages using Visual Studio 2017 Preview 2:

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);
        }
    }
}

Browser

http://localhost:44322/postJson




回答6:


Accepted solution worked in local developing machine, but failed then deployed in Debian server behind Nginx reverse proxy (not found 404 error).

This is a working example with payload data:

<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 Pages; jQuery 3.3.1



来源:https://stackoverflow.com/questions/46410716/example-ajax-call-back-to-an-asp-net-core-razor-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!