J'ai trouvé des exemples de plusieurs gestionnaires sur une page et la convention de dénomination associée (c'est-à-dire OnPostXXX) et l'aide de balise 'asp-post-hanlder'. Mais comment puis-je appeler l'une de ces méthodes à partir d'un appel AJAX.
J'ai un exemple plus ancien avec une vue et un contrôleur MVC typiques, mais comment cela fonctionne-t-il avec une page Razor?
Par exemple si je prends l'application de base et modifie la page About.cshtml comme suit:
@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>
}
Et sur la page du modèle 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("");
}
}
OnPost n'est pas appelé depuis l'appel Ajax.
Le jeton AntiForgery doit être ajouté et il doit y avoir un élément de formulaire sur la page.
dans votre Startup.Cs Ajoutez ceci avant services.AddMvc ()
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
thenn dans votre ajax, changer à:
$.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);
})
}
puis dans votre méthode ajouter
[ValidateAntiForgeryToken]
public IActionResult OnPost()
{
//throw new Exception("stop");
return new JsonResult ("Hello Response Back");
}
Sur la page cshtml, enveloppez le bouton dans un formulaire ou aucun cookie AntiForgery ne sera ajouté.
<form method="post">
<input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" />
</form>
Veuillez consulter cette section connexe de la documentation https://docs.Microsoft.com/en-us/aspnet/core/mvc/razor-pages/?tabs=visual-studio
Les associations de chemins d’URL aux pages sont déterminées par l’emplacement de la page dans le système de fichiers. Le tableau suivant montre un chemin de page Razor et l'URL correspondante.
/Pages/Index.cshtml est mappé sur/ou/Index
/Pages/Contact.cshtml est mappé sur/Contact
La solution acceptée fonctionnait sur la machine en développement locale, mais a échoué puis déployée sur le serveur Debian derrière le proxy inverse Nginx (erreur 404 non trouvée).
Voici un exemple de travail avec des données utiles:
<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
Tout fonctionne bien, mais quelques modifications doivent être apportées:
1) Ouvrez Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
services.AddMvc();
}
2) Ouvrez HomeController.cs:
[ValidateAntiForgeryToken]
public IActionResult OnPost()
{
return new JsonResult("Hello Response Back");
}
3) Ouvrez 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>
Il est à noter que "onPost" a été ajouté à l'intérieur du contrôleur. Par conséquent, dans AJAX, le "url" correct doit être indiqué. Ensuite:
url: 'onPost',
La réponse fonctionne pour moi. Je voudrais seulement ajouter que si nous avons des méthodes personnalisées sur la page comme:
public IActionResult OnPostFilter1()
{
return new JsonResult("Hello Response Back");
}
Ensuite, nous devrions spécifier le nom du gestionnaire dans l'URL:
url: 'OnPost?handler=filter1',
Après avoir examiné les réponses ci-dessus, JSON ajax est devenu compatible avec les pages .NET Core 2.1 Razor à l'aide de 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);
}
}
}
Navigateur