我看到了一些关于 Ajax Post 方法的不同问题,但似乎没有一个能解决我的问题。
我有一个部分视图,它在客户端通过 JavaScript 创建一个对象数组,我想获取该数组,然后将其作为 T 列表的 C# 类型传递到 Razor Pages 应用程序中的文件后面的页面( T 是我的自定义对象注)。
不幸的是,当数据返回到我的 OnPostAddNotes 方法时,List 始终为空。当仅使用 Note 类作为模型时,数据按预期传递,但由于某种原因我无法让它传递“Note”列表。
“顶层模型”是一个Character Detail Model,它有一个CharacterNotes属性,它是一个Note类型的List。
模型/角色.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace RPGInfo.Web.Models
{
public class Character : BaseEntity
{
public List<Note> CharacterNotes { get; set; } = new List<Note>();
}
}
CharacterNotes 的类型是具有这些属性的注释列表。
模型/CharacterNote.cs
using System;
using System.ComponentModel.DataAnnotations;
namespace RPGInfo.Web.Models
{
public class Note : BaseEntity
{
[Required]
[MaxLength(40)]
public string NoteTitle { get; set; }
public DateTime NoteDate { get; set; }
[Required]
[MaxLength(500)]
public string NoteContent { get; set; }
}
}
这是主视图,其模型为角色细节模型。有部分人物注释。
视图/CharacterDetail.cshtml
@page "{id}"
@model RPGInfo.Web.Pages.CharacterDetailModel
@model {
ViewData["Title"] = "Character Detail";
}
<div>
<partial name="_CharacterNotePartial" model="@Model.CharacterNotes" />
</div>
用于创建笔记的部分视图。这是我尝试将 Note 对象列表发送到代码隐藏文件中的 OnPostAddNote 方法的地方。
共享/_CharacterNotesPartial.cshtml
@using RPGInfo.Web.Models
@model List<Note>
<h4>Character Notes</h4>
<div class="row">
<ul class="list-group col-12" id="newNote">
</ul>
</div>
<form asp-page-handler="AddNotes" class="mt-4 mb-4">
<div class="row">
<div class="form-group col-6">
<label for="NoteTitle">Title</label>
<input type="text" id="noteTitle" name="NoteTitle" class="form-control">
</div>
<div class="form-group col-6">
<label for="NoteDate">Date</label>
<input type="datetime" id="noteDate" name="NoteDate" class="form-control">
</div>
</div>
<div class="form-group">
<label for="NoteContent">Content</label>
<input type="text" id="noteContent" name="NoteContent" class="form-control">
</div>
<button type="button" id="addNoteForm" class="btn btn-primary">Note Add</button>
@Html.AntiForgeryToken()
<button class="btn btn-primary" type="button" onclick="addCurrentNotes(data)"> Submit Added Notes</button>
</form>
<style>
.note-style {
word-wrap: break-word;
}
</style>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript">
data = [];
$("#addNoteForm").click(function() {
addNote();
});
$("#removeNote").click(function() {
removeNote();
});
function addData(item) {
data.push(item);
console.log(data);
}
function removeData(itemToRemove) {
$(itemToRemove).on("click", itemToRemove, function() {
$(this).remove();
var index = data.indexOf(itemToRemove.text());
console.log(index);
data.splice(index, 1);
console.log(data);
});
}
function addNote() {
var noteTitle = $('input[id="noteTitle"]').val();
var noteDate = $('input[id="noteDate"]').val();
var noteContent = $('input[id="noteContent"]').val();
var listItemId = getListItemId(4).toLowerCase();
console.log(listItemId + ' ' + noteDate + ' ' + noteTitle + ' ' + noteContent);
var listItemToAppend = '<li id="li-'+ listItemId + '" class="list-group-item rmv_btn'+ listItemId + '">'
+ '<div class="row">'
+ '<div class="col-10 note-style">'
+ noteTitle + ' ' + noteDate + ' ' + noteContent
+ '</div>'
+ '<div class="col-2">'
+ '<button type="button" id="btn-'+ listItemId +'" class="rmv_btn'+ listItemId + ' btn btn-danger btn-sm">' + "Remove" + '</button>'
+ '</div>'
+ '</div>'
+ '</li>'
$("#newNote").append(listItemToAppend);
var newItem = $('#newNote').find('#li-'+ listItemId).text();
addData(newItem);
var itemToRemove = $('#newNote').find('#li-'+ listItemId);
removeData(itemToRemove);
}
function getListItemId(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = 4;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
}
return result;
}
function addCurrentNotes() {
var notes = [];
for(let i = 0; i < 2; i++) {
var note = {};
note.noteTitle = "";
note.noteDate = "";
note.noteContent = "Content" + i;
notes.push(note);
}
notes = JSON.stringify(notes);
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'post',
url: window.location.href + "?handler=AddNotes",
data: notes,
success: function() {
window.location.href="url";
},
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
}
});
};
</script>
点击=AddCurrentNotes(data)发送数据的函数和Ajax方法。我尝试在 Note 中添加和删除各种属性来构建 JSON,但没有一个属性被发送到 post 方法上的参数。
文件后面的页面有一个“OnPostAddNotes”方法,该方法连接到提交按钮并接收注释列表参数。注释列表参数返回的计数始终为 0。如果我从注释列表切换为仅注释作为模型,它会按预期工作,但列表不会。
页面/角色/CharacterDetail.cshtml.cs
namespace RPGInfo.Web.Pages
{
public class CharacterDetailModel : PageModel
{
[BindProperty]
public Character Character { get; set; }
public void OnGet(int id)
{
Character = _context.Characters.Where(x => x.Id == id).FirstOrDefault();
Character.CharacterNotes = _context.Notes.Where(note => note.CharacterId == id).ToList();
}
[BindProperty]
public Note CharacterNote { get; set; }
[BindProperty]
public List<Note> CharacterNotes { get; set; }
public ActionResult OnPostAddNotes([FromBody]List<Note> notes)
{
// **List<Note> is null here**
return RedirectToPage();
}
}
在客户端,注释是通过 JavaScript 创建的,在查看有效负载时,该对象看起来结构正确,但是,网络选项卡仅将 Ajax 方法显示为待处理。
我更改了 Ajax 函数中的日期,并且该日期显示在有效负载中,不幸的是,
List<Note>
在我的 CharacterDetail.cshtml.cs 文件中仍然返回为 null。
不确定从你的局部视图来看你的
data
是什么,但这并不重要。我看到您的有效负载成功包含数据。因此,我只是对有效负载进行了硬编码以便于测试,并为您提供了一个工作演示:
你可以看到你的
Network
包含了两个对该处理程序的请求,这是因为<button>
元素默认类型是submit,所以它会首先将表单数据提交到后端。添加如下 type="button"
以避免多次请求:
<button class="btn btn-primary" type="button" onclick="addCurrentNotes()">Submit Added Notes</button>
更改你的js,如下所示:
注意:请给出 noteDate 日期时间格式默认值,而不是空字符串。
function addCurrentNotes(){
var notes=[];
for(let i =0; i < 2;i++)
{
var note = {};
note.noteTitle="";
note.noteDate=new Date('0001-01-01'); //change here....
note.noteContent="Content"+i;
notes.push(note);
}
notes=JSON.stringify(notes); //change here.....
$.ajax({
contentType:"application/json; charset=utf-8",
dataType:'json',
type:'post',
url:window.location.href+"?handler=AddNotes",
data:notes,
success:function()
{
console.log("suceess");
},
beforeSend:function(xhr){
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
}
})
}
在后端代码中添加
[FromBody]
:
public ActionResult OnPostAddNotes([FromBody]List<Note> notes)
{
return RedirectToPage();
}
备注:
Ajax 无法与 RedirectToPage 配合使用,如果想在 ajax 回发时重定向,需要在 success 函数中添加
window.location.href="url"
。
样品模型
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
}
后端代码
public IActionResult OnPostSaveData(List<Test> objTest)
{
//do whatever you want
}
并在您的前端文件中添加ajax调用,如下所示
var urlVal = "@Url.Page("/index/")?handler=SaveData";
$.ajax({
type: "POST",
url: urlVal,
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: {
"objTest": [{ "ID": 1, "Name": "buddhika" }, { "ID": 2, "Name": "buddhika123" }]
},
success: function (response) {
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});