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

时间:2022-02-15 03:16:59

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.

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

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

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

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

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

And on the model page About.cshtml.cs

在模型页面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.

不从Ajax调用调用OnPost。

5 个解决方案

#1


8  

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

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

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

在你的Startup.Cs中添加这个在services.AddMvc()之前

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

thenn in your ajax, change to:

然后在你的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);
        })

    }

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.

在cshtml页面上,在表单中包装按钮,或者不添加AntiForgery cookie。

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

#2


1  

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

请参阅文档的相关部分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

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

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

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

/Pages/Contact.cshtml maps to /Contact

/Pages/Contact.cshtml映射到/联系人

#3


0  

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中指定处理程序名称:

url: 'OnPost?handler=filter1',

#4


0  

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:

在查看上面的答案后,我使用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);
        }
    }
}

Browser

http://localhost:44322/postJson

#5


-1  

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:

应该注意的是,在控制器内添加了“onPost”,因此在AJAX中应该指出正确的“url”。然后:

url: 'onPost',

#1


8  

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

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

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

在你的Startup.Cs中添加这个在services.AddMvc()之前

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

thenn in your ajax, change to:

然后在你的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);
        })

    }

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.

在cshtml页面上,在表单中包装按钮,或者不添加AntiForgery cookie。

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

#2


1  

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

请参阅文档的相关部分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

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

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

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

/Pages/Contact.cshtml maps to /Contact

/Pages/Contact.cshtml映射到/联系人

#3


0  

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中指定处理程序名称:

url: 'OnPost?handler=filter1',

#4


0  

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:

在查看上面的答案后,我使用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);
        }
    }
}

Browser

http://localhost:44322/postJson

#5


-1  

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:

应该注意的是,在控制器内添加了“onPost”,因此在AJAX中应该指出正确的“url”。然后:

url: 'onPost',