简体   繁体   English

Ajax:将模型从由 foreach 循环迭代的列表发送到控制器

[英]Ajax: Send a model to controller from list iterated by foreach loop

I need to be able to send a list of a model back to the controller from a view but only when the input has been checked.我需要能够将模型列表从视图发送回控制器,但仅当输入已被检查时。

Using AJAX I can get it working but the page refreshes and I don't catch the data but it does show up in the URL.使用 AJAX 我可以让它工作,但页面刷新,我没有捕获数据,但它确实显示在 URL 中。 Example: https://localhost:44308/PlayTest/PlayTest?personName=Test+User&DevOps-rate=3&Software+Development-rate=2&Solution+Architecture-rate=1&comments=&save=Save示例: https://localhost:44308/PlayTest/PlayTest?personName=Test+User&DevOps-rate=3&Software+Development-rate=2&Solution+Architecture-rate=1&comments=&save=Save

But when I try and use Javascript and JQuery, I'm only able to catch the "person name" not the comments or rates in the post method.但是当我尝试使用 Javascript 和 JQuery 时,我只能捕获“人名”,而不是 post 方法中的评论或费率。

HTML HTML

<div class="tabcontent" id="testing">
  <form name="skillform"
        id="skillform"
        asp-action="SaveRecord"
        asp-controller="YourSkills"
        data-ajax="true"
        data-ajax-method="post">
      <h3 class="tab-title">Testing</h3>
      @foreach (var item in Model.Skills)
      {
          @if (item.SkillGroupID == 2)
          {
              <div class="star-rating">
                  <h5 class="skill-name" id="skill-title">@item.SkillName</h5>
                  <input type="radio" id="@item.SkillName@item.SkillGroupID-star3" name="@item.SkillName-rate" value="3" /><label for="@item.SkillName@item.SkillGroupID-star3" title="Advanced - 3 Stars">3 Stars</label>
                  <input type="radio" id="@item.SkillName@item.SkillGroupID-star2" name="@item.SkillName-rate" value="2" /><label for="@item.SkillName@item.SkillGroupID-star2" title="Intermediate - 2 Stars">2 Stars</label>
                  <input type="radio" id="@item.SkillName@item.SkillGroupID-star1" name="@item.SkillName-rate" value="1" /><label for="@item.SkillName@item.SkillGroupID-star1" title="Beginner - 1 Star">1 Stars</label>
              </div>
              <br />
              <br />
          }
      }
      <div class="comments">
          <h6 class="comment-name">Comments</h6>
          <textarea rows="4" cols="50" name="comments" id="comment-text-area" spellcheck="true"></textarea>
      </div>
      <div class="buttons">
          <input type="reset" value="Clear">
          <button type="button" class="edit" onclick="alert('This will allow the tab to be edited')">Edit</button> <!--add cancel button when opened-->
          <input type="submit" name="save" value="Save" id="btnSave" skill-group="2"/>
      </div>
  </form>
</div>

Post Method邮寄方式

public JsonResult SaveRecord(string PersonName, List<SkillsModel> skill, string comment)
{
    SkillsMatrixDB database = HttpContext.RequestServices.GetService(typeof(SkillsMatrix.Models.SkillsMatrixDB)) as SkillsMatrixDB;
    List<PersonModel> people = database.GetAllPeople();

    PersonModel recordingPerson = FindPerson(people, PersonName);

    if (skill.Count() > 1)
    {
        for (int i = 0; i < skill.Count(); i++)
        {
            RecordsModel records = new RecordsModel();
            records.PersonID = recordingPerson.PersonID;
            records.SkillGroupID = skill[i].SkillGroupID;
            records.SkillID = skill[i].SkillID;
            records.SkillLevelID = Convert.ToInt32(HttpContext.Request.Form[skill[i].SkillName + skill[i].SkillGroupID + "-rate"]);
            records.Comments = HttpContext.Request.Form["comments"].ToString();
            records.DateSaved = DateTime.Now;
            records.YearlyQuarter = DateTime.Now.Month / 3;
            //database.SaveRecord(records);
        }
    }
    else if (skill.Count() == 1)
    {
        RecordsModel records = new RecordsModel();
        records.PersonID = recordingPerson.PersonID;
        records.SkillGroupID = skill[0].SkillGroupID;
        records.SkillID = skill[0].SkillID;
        records.SkillLevelID = Convert.ToInt32(HttpContext.Request.Form[skill[0].SkillName + skill[0].SkillGroupID + "-rate"]);
        records.Comments = HttpContext.Request.Form["comments"].ToString();
        records.DateSaved = DateTime.Now;
        records.YearlyQuarter = DateTime.Now.Month / 3;
        //database.SaveRecord(records);
    }

    return Json(recordingPerson.Name);
}

JS JS

$(document).ready(function () {
    $("#btnSave").click(function () {
        $.ajax({
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            type: "POST", //HTTP POST Method
            url: "YourSkills/SaveRecord", //Controller/View
            data: $('#skillform').serialize(),
            success: function (data) {
                console.log(data);
                alert('You saved it!');
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log(textStatus);
                alert('Something went wrong. save failed!');
            }
        });
    });
});

I feel like the way I've read to make the list in JS is wrong and to catch the data is not all that correct either.我觉得我在 JS 中制作列表的方式是错误的,并且捕获数据也不是那么正确。 If someone could help that would be great.如果有人可以提供帮助,那就太好了。 I'm so confused why doing it without JS works and picks up the right data but for some reason, I can't.我很困惑为什么在没有 JS 的情况下这样做可以工作并获取正确的数据,但出于某种原因,我不能。

EDIT I have tried what Emiel Zuurbier said but I am using Visual Studio 2019 and In the console, all I am getting is the following:编辑我已经尝试了 Emiel Zuurbier 所说的,但我使用的是 Visual Studio 2019 并且在控制台中,我得到的只是以下内容:

Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 POST https://localhost:44308/PlayTest/YourSkills/SaveRecord application/json; charset=UTF-8 235
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 6.0162ms 404 
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 POST https://localhost:44308/PlayTest/SaveRecord application/x-www-form-urlencoded 233
Failed to load resource: the server responded with a status of 404 () [https://localhost:44308/PlayTest/YourSkills/SaveRecord]
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint 'SkillsMatrix.Controllers.PlayTestController.SaveRecord (SkillsMatrix)'
error
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Information: Route matched with {action = "SaveRecord", controller = "PlayTest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.JsonResult SaveRecord(System.String, System.Collections.Generic.List`1[SkillsMatrix.Models.SkillsModel], System.String) on controller SkillsMatrix.Controllers.PlayTestController (SkillsMatrix).

page reloading may happens because the error occurred in js execution while you are creating skills object.as its not the right way页面重新加载可能是因为在创建技能对象时在 js 执行中发生错误。因为它不是正确的方法
define skills object this way rest of the things look good.以这种方式定义技能对象其余的东西看起来不错。

 let skills = {};
skills['SkillID']  = $("#skill-id").val();
skills['SkillGroupID']  = $(this).attr('skill-group');
skills['SkillName']  = $("#skill-title").val();

Your page is being reloaded because you are submitting the form whenever you click the the #btnSave button.您的页面正在重新加载,因为您在每次单击#btnSave按钮时都在提交表单。 What you want to do is listen for the submit event on the form itself and cancel it with event.preventDefault() .你想要做的是监听表单本身的submit事件并用event.preventDefault()取消它。 This allows you to create your own submission behavior when submitting.这允许您在提交时创建自己的提交行为。 And prevents the form from reloading the page.并防止表单重新加载页面。

$(document).ready(function() {
  $('#skillform').on('submit', function(event) {
    ...
    event.preventDefault();
  });
});

Your HTML seems to miss the #skill-id element.您的 HTML 似乎缺少#skill-id元素。 If you mean to include data from your form into your controller then I suggest that you use hidden input fields instead of reading attributes from your elements.如果您打算将表单中的数据包含到控制器中,那么我建议您使用隐藏的输入字段,而不是从元素中读取属性。

<input type="hidden" name="skill-name" value="">
<input type="hidden" name="skill-id" value="">
<input type="hidden" name="skill-group" value="">

These fields will not be visible to the user but will contain data that the server is able to read.这些字段对用户不可见,但将包含服务器能够读取的数据。

Then instead of use .val() to get each individual field use $('form').serialize() to extract the name and value pairs out of the form and use them in your AJAX request.然后使用$('form').serialize()$('form').serialize()中提取名称和值对并在您的 AJAX 请求中使用它们,而不是使用.val()来获取每个单独的字段。 This way you are sending the same data as you would with a normal submit.通过这种方式,您将发送与正常提交相同的数据。

$.ajax({
  contentType: 'application/json; charset=utf-8',
  dataType: 'json', 
  type: "POST",
  url: "YourSkills/SaveRecord",
  data: $('#skillform').serialize(); // <-- Get all values from the form.
  success: function (data) { // <-- data is the response you receive from the controller.
    console.log(data); 
    alert('You saved it!');
  },
  error: function (jqXHR, textStatus, errorThrown) {
    alert('Something went wrong. save failed!');
  }
});

I recommend that you check the $.ajax docs to use the correct methods and notation to use the function properly.我建议您检查$.ajax文档以使用正确的方法和符号来正确使用该函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM