【问题标题】:Ajax: Send a model to controller from list iterated by foreach loopAjax:从 foreach 循环迭代的列表中向控制器发送模型
【发布时间】:2020-03-19 15:25:48
【问题描述】:

我需要能够将模型列表从视图发送回控制器,但前提是输入已被检查。

使用 AJAX 我可以让它工作,但页面会刷新,我没有捕捉到数据,但它确实显示在 URL 中。示例:https://localhost:44308/PlayTest/PlayTest?personName=Test+User&DevOps-rate=3&Software+Development-rate=2&Solution+Architecture-rate=1&comments=&save=Save

但是当我尝试使用 Javascript 和 JQuery 时,我只能捕捉到“人名”,而不是 post 方法中的 cmets 或 rate。

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>

发布方式

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

$(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!');
            }
        });
    });
});

我觉得我在 JS 中创建列表的方式是错误的,并且捕获数据也不是那么正确。如果有人可以提供帮助,那就太好了。我很困惑为什么在没有 JS 的情况下这样做可以工作并获取正确的数据,但由于某种原因,我不能。

编辑 我已经尝试过 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).

【问题讨论】:

    标签: javascript jquery ajax asp.net-mvc


    【解决方案1】:

    您的页面正在重新加载,因为您每次单击#btnSave 按钮时都在提交表单。您要做的是在表单本身上监听submit 事件并使用event.preventDefault() 取消它。这允许您在提交时创建自己的提交行为。并防止表单重新加载页面。

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

    您的 HTML 似乎缺少 #skill-id 元素。如果您打算将表单中的数据包含到控制器中,那么我建议您使用隐藏的输入字段而不是从元素中读取属性。

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

    这些字段对用户不可见,但会包含服务器能够读取的数据。

    然后,不要使用 .val() 来获取每个单独的字段,而是使用 $('form').serialize() 从表单中提取名称和值对并在 AJAX 请求中使用它们。这样,您发送的数据与普通提交时相同。

    $.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!');
      }
    });
    

    我建议您检查$.ajax 文档以使用正确的方法和符号来正确使用该功能。

    【讨论】:

    • 我已经改成了这个,但现在它一直处于错误状态,当它调用“SaveRecord”函数时,只有“PersonName”被填充。我看到序列化如何给我与 url 相同的结果,但为什么它会出错,为什么它不能正确收集表单数据。
    • 在错误处理程序中记录textStatus 值。然后查看您的控制台以发现错误的含义。
    • 我已经尝试过了,并在原始问题中发布了控制台,因为它对于此评论来说太大了。
    • 您收到 404 错误。这意味着永远无法到达您的 "YourSkills/SaveRecord" 端点。您的原始表单没有指定方法,这意味着它回退到GET 方法。因此,您可以尝试在$.ajax 函数中将POST 更改为GET。我还在网上看到了多个使用 asp.net 实现 API 结构的示例。可能值得一试。 api tutorial
    • 啊,谢谢,我注意到我的 Post 方法实际上也没有 [Http Post] 标签,这没有帮助。从 POST 到 GET 的变化帮助我看到了控制台中的调用,所以我现在可以看到它了,谢谢。
    【解决方案2】:

    可能会发生页面重新加载,因为在您创建技能对象时执行 js 时发生错误。因为它不是正确的方法
    以这种方式定义技能对象,其余的看起来都不错。

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

    【讨论】:

    • 不幸的是,这并没有帮助解决问题。但是无论如何谢谢你:)
    • 尝试在您单击的那一刻创建您的数据对象,然后将其登录到控制台以在通过 ajax 发送之前检查您是否获得了有效数据
    猜你喜欢
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2020-05-29
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    相关资源
    最近更新 更多