【问题标题】:ASP.NET MVC Controller FileContent ActionResult called via AJAX通过 AJAX 调用的 ASP.NET MVC 控制器 FileContent ActionResult
【发布时间】:2010-02-10 22:39:34
【问题描述】:

设置:

控制器包含一个方法public ActionResult SaveFile(),它返回一个FileContentResult。

什么有效:

视图包含一个表单,它提交给这个动作。结果是这个对话框:

什么不起作用:

视图包含一些 javascript,用于对表单发布的同一控制器操作进行 AJAX 调用。响应不会触发上述对话框,甚至 AJAX 成功函数,而是触发 AJAX 错误函数,XMLHttpRequest.responseText 包含文件响应。

我需要做什么:

使用 AJAX 请求文件,最终得到与提交表单时相同的结果。如何让 AJAX 请求提供提交表单时显示的对话框?

【问题讨论】:

  • 为什么不能只使用非ajax调用?
  • 可以,但我想在保存完成后在 javaScript 函数中进行一些其他处理,例如取消阻止表单,这是我在保存之前阻止的。
  • OK,这样就可以先调用ajax SaveFile了。 SaveFile 将返回真/假。当它返回 true 时,您调用非 ajax GET 来获取文件。
  • 当我从 jquery.ajax 调用控制器的 SaveFile 时,没有弹出浏览器的下载对话框。真正的问题是我想在保存期间阻止 UI。我可以保存得很好(提交表单的正常后期处理),但是我无法启动 blockUI。我可以捕获一个事件(按钮单击或提交处理程序,启动块并显示繁忙指示器,但随后我无法触发解锁。有没有办法从控制器的 Action 调用 jQuery 函数,以便我可以触发解锁。我没有没有注意到我可以使用的任何事件。这就是我尝试通过 Ajax 调用进行调用的原因。
  • 好的,你仍然可以使用ajax,但不要返回FileContentResult。返回 true/false,如果返回 true,则初始化非 ajax get 下载文件。

标签: asp.net asp.net-mvc ajax


【解决方案1】:

这是我编造的一个简单示例。这是 LukLed 在调用 SaveFile 时所说的概念,但不通过 ajax 返回文件内容,而是重定向到下载。

查看代码如下:

<script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function() {
        // hide form code here

        // upload to server
        $('#btnUpload').click(function() {
            $.ajax({
                type: 'POST',
                dataType: 'json',
                url: '<%= Url.Action("SaveFile", "Home") %>',
                success: function(fileId) {
                    window.location = '<%= Url.Action("DownloadFile", "Home") %>?fileId=' + fileId;
                },
                error: function() {
                    alert('An error occurred uploading data.');
                }
            });
        });
    });
</script>

<% using (Html.BeginForm()) { %>

    <div>Field 1: <%= Html.TextBox("field1") %></div>

    <div>Field 2: <%= Html.TextBox("field2") %></div>

    <div>Field 3: <%= Html.TextBox("field3") %></div>

    <button id="btnUpload" type="button">Upload</button>

<% } %>

这是控制器代码:

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public JsonResult SaveFile(string field1, string field2, string field3)
    {
        // save the data to the database or where ever
        int savedFileId = 1;

        // return the saved file id to the browser
        return Json(savedFileId);
    }

    public FileContentResult DownloadFile(int fileId)
    {
        // load file content from db or file system
        string fileContents = "field1,field2,field3";

        // convert to byte array
        // use a different encoding if needed
        var encoding = new System.Text.ASCIIEncoding();
        byte[] returnContent = encoding.GetBytes(fileContents);

        return File(returnContent, "application/CSV", "test.csv");
    }

    public ActionResult About()
    {
        return View();
    }
}

【讨论】:

  • Nate,感谢您提供如此详细的示例。我很感激,也感谢 LukLed 努力解释您的解决方案。没有陷入困境的一点是,第一个调用准备了要保存的数据,第二个调用进行了下载。
  • 在我把头撞到墙上说 WTF 试图理解之前,我去过那里,不用担心。很高兴能提供帮助。
猜你喜欢
  • 2010-12-21
  • 2023-03-28
  • 1970-01-01
  • 2015-05-17
  • 2016-11-08
  • 2020-07-16
  • 2014-06-17
  • 1970-01-01
  • 2017-11-16
相关资源
最近更新 更多