【问题标题】:Ajax to MVC POST request: Redirection issue, "Page not working"Ajax 到 MVC POST 请求:重定向问题,“页面不工作”
【发布时间】:2021-03-01 15:39:29
【问题描述】:

在我的 Post 请求(从 AJAX 到控制器)之后,我遇到了一个小问题。基本上,post 请求发生,它在控制器中执行函数,然而,在它执行 ajax 调用之后,我得到以下页面:

我不知道为什么会这样,希望能得到一些帮助。我以前没有用过这种东西。 以下是一些可以提供帮助的代码 sn-ps:

已编辑 .js 文件:

    function Export() {
   

    var donations = new Array();
    $("#Donations tbody tr").each(function () {
        var row = $(this);
        var donation = {};
        donation.Name = row.find("td").eq(0)[0].innerText;
        donation.DOB = row.find("td").eq(1)[0].innerText;
        donation.DOD = row.find("td").eq(2)[0].innerText;
        donation.COD = row.find("td").eq(3)[0].innerText;
        donation.CaseNumber = row.find("td").eq(4)[0].innerText;
        donations.push(donation);
    });

    
    $.ajax({
        type: "POST",
        url: "/Donation/Export",
        data: JSON.stringify(donations),
        dataType: "json",
        success: function (data) {
            console.log("file saved: ", data);            
        }
    }).done(function () {
        window.location.href = '@Url.Action("Download", "DonationController", new { csv = data }))';
    });;
};

已编辑 Index.cshtml:

 @using (Html.BeginForm())
{

    <p>
        <input type="submit" class="btn btn-outline-primary btn-sm" value="Export" onclick="Export()" />

    </p>


    <table id="Donations" class="table">
        <thead>
            <tr>
                <th>Full Name</th>
                <th>@Html.DisplayNameFor(model => model.Person.DateOfBirth)</th>
                <th>@Html.DisplayNameFor(model => model.Donation.DateOfDeath)</th>
                <th>@Html.DisplayNameFor(model => model.Donation.CauseOfDeath)</th>
                <th>@Html.DisplayNameFor(model => model.Donation.CaseNumber)</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Donations)
            {
                <tr>
                    <td><a asp-action="Details" asp-controller="Person" asp-route-id="@item.PersonId">@Html.DisplayFor(modelItem => item.Person.Title) @Html.DisplayFor(modelItem => item.Person.Forenames) @Html.DisplayFor(modelItem => item.Person.Surname)</a></td>
                    <td>@Html.DisplayFor(modelItem => item.Person.DateOfBirth)</td>
                    <td>@Html.DisplayFor(modelItem => item.DateOfDeath)</td>
                    <td>@Html.DisplayFor(modelItem => item.CauseOfDeath)</td>
                    <td><a asp-action="Details" asp-controller="Donation" asp-route-id="@item.PersonId">@Html.DisplayFor(modelItem => item.CaseNumber)</a></td>
                </tr>
            }
        </tbody>
    </table>
}

已编辑 DonationController.cs:

[HttpPost]
        public string Export()
       
        {
                    
            var resolveRequest = HttpContext.Request;         
           
            string[] columnNames = { "Name", "DOB","DateOfDeath", "CauseOfDeath", "CaseNumber" };

            //Build the CSV file data as a Comma separated string.
            string csv = string.Empty;

            foreach (string columnName in columnNames)
            {
                //Add the Header row for CSV file.
                csv += columnName + ',';
            }

            //Add new line.
            csv += "\r\n";

            foreach (string k in resolveRequest.Form.Keys)
            {
                using JsonDocument doc = JsonDocument.Parse(k);
                JsonElement root = doc.RootElement;;
                var users = root.EnumerateArray();

                while (users.MoveNext())
                {
                    var user = users.Current;
                    var props = user.EnumerateObject();

                    while (props.MoveNext())
                    {
                        var prop = props.Current;                        
                        csv += String.IsNullOrEmpty(prop.Value.ToString()) ? "," : prop.Value.ToString().Replace(",", ";") + ',';
                        //Console.WriteLine($"{prop.Name}: {prop.Value}");
                    }
                    csv += "\r\n";
                }

                
            }           
            
            
            return (csv);
            
            
        }

        public FileContentResult Download(string csv)
        {
            //Download the CSV file.
            byte[] bytes = Encoding.ASCII.GetBytes(csv);
            return File(bytes, "application/text", "Donations.csv");
           
    }

【问题讨论】:

  • 您是否尝试过[FromForm] 而不是在控制器中使用[FromBody]?但是控制器必须知道来自视图的数据并且它可以处理。您的主要问题是什么:不要使用 Ajax 发布请求到达控制器?或者从帖子中获取数据后重定向问题? @HK1232
  • @Gökhan Aldanmaz 问题是后者,从帖子获取数据后的重定向问题。基本上,只要我单击 Export 按钮,就会进行 ajax post 调用,然后它会转到控制器中的 Export 函数,这就是我收到 415 错误的时候(甚至在它到达 return 语句 -im 调试之前)。我只是尝试了 [FromForm],但发布的数据现在为空。

标签: asp.net-core-mvc http-post asp.net-ajax


【解决方案1】:

文件不能作为查询字符串传递,这将导致负载格式为不受支持的格式。这将导致415 error

在您的Export 方法中(IActionResult,return a Jsonresult):

[HttpPost]
public IActionResult Export([FromBody] List<ExportedValues> values)
    {
      //...
      return new JsonResult (new {csv = csv });
    }

然后在您的Download 方法中:

 public FileContentResult Download(string csv)
   {
       return File(//Convert to your file)
   }

在你的 ajax 中:

$.ajax({
    type: "POST",
    url: "/Donation/Export",
    data: JSON.stringify(donations),
    dataType: "json",
    success: function (data) {
                console.log("file saved: ", data);
                window.location = '/Donation/Download?csv=' + data.csv;
            }
        });

【讨论】:

  • 您好,感谢您的反馈。我按照您的建议更新了我的代码,但是我仍然收到 415 错误。基本上,只要我单击 Export 按钮,就会进行 ajax post 调用,然后它会转到控制器中的 Export 函数,这就是我收到 415 错误的时候(甚至在它到达 Export 的 return 语句之前)。那么根据您的建议,我是否可以从 ajax 成功调用 Download 函数?
  • 我在帖子中编辑了我的代码,我不再收到 415 错误,太好了!但我可能在调用 Download 函数时做错了,因为在 Export 中返回 csv 字符串后它不会去那里。知道有什么问题吗?再次感谢我感谢您的帮助。抱歉,如果这些是基本问题,我根本没有做太多工作。谢谢
  • 嗨@HK1232,我已经更新了我的答案,你可以检查一下。
  • 非常感谢!!!!我调整了一些并将您的更改添加到我的代码中,它运行良好。再次感谢您的响应!
猜你喜欢
  • 2015-12-13
  • 1970-01-01
  • 2018-07-10
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
相关资源
最近更新 更多