如何将列表<T>从 Ajax Post 传递到 ASP.NET Razor 页面代码隐藏

问题描述 投票:0回答:2

我看到了一些关于 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。

javascript jquery ajax asp.net-core razor-pages
2个回答
1
投票

不确定从你的局部视图来看你的

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"


1
投票

样品模型

 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);
            }
        });
© www.soinside.com 2019 - 2024. All rights reserved.