Asp.net更新部分视图并下载文件

时间:2018-02-20 18:44:03

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

我有一个网站,其中包含下载列表以及包含已下载文件历史记录的列表。 当我点击一个我想要的时候,所选文件的下载开始,新项目被添加到历史记录中。 下载到目前为止工作:

    public async Task<ActionResult> DownloadSelection(int selectionId, DownloadFormat format)
    {
        var selection = databaseSelectionService.GetById(selectionId);

        string fileName = selection.Name + FileNamingHelper.GetFileExtensionByFormat(format);
        var fileBytes = await downloadManager.ExecuteSelection(selection, applicationUserManager.FindById(User.Identity.GetUserId()), format);
        return File(fileBytes, MediaTypeNames.Application.Octet, fileName);
    }

我通过HTML.ActionLink调用它:

@Html.ActionLink(Strings.ExcelLabel, "DownloadSelection", "Home", new { selectionId = selection.Id, format = DownloadFormat.Excel }, null)

现在我的问题是,要刷新历史记录,我必须返回部分视图。但是因为我已经将File作为ActionResult返回,所以我也无法返回部分View。

我尝试了一种方法来使用Ajax.ActionLink并为OnSuccess添加一个AjaxOption,以便在下载成功后调用第二个控制器,并返回部分视图。但不知怎的,我的javascript函数从未被调用过。

@section scripts
{
    function testFunction()
    {
        alert("huhu");
    }
}

@Ajax.ActionLink(Strings.CsvLabel, "DownloadSelection", "Home", new { selectionId = selection.Id, format = DownloadFormat.CSV }, new AjaxOptions{OnSuccess = "testFunction" })

解决这个问题的好方法是什么?

查看:

@{
    ViewBag.Title = Strings.SelectionsTitle;
}

<h2>@ViewBag.Title</h2>

@if (Model.AssignedDatabaseSelections.Any())
{
    <table>
        <tr>
            <th>Abfrage</th>
            <th style="text-align:right">Download</th>
        </tr>
        @foreach (var selection in Model.AssignedDatabaseSelections)
        {
            <tr>
                <td>@selection.DisplayName</td>
                <td style="text-align:right">
                   @Ajax.ActionLink(Strings.CsvLabel, "DownloadSelection", "Home", new { selectionId = selection.Id, format = DownloadFormat.CSV }, new AjaxOptions{OnSuccess = "testFunction" })  |
                   @Ajax.ActionLink(Strings.ExcelLabel, "DownloadSelection", "Home", new { selectionId = selection.Id, format = DownloadFormat.Excel}, new AjaxOptions{OnSuccess = "testFunction" })
                </td>
            </tr>
        }
    </table>
}
else
{
    <div>
        @Strings.NoSelectionsPlaceholder
    </div>
}

<h2>@Strings.DownloadHistoryTitle</h2>

@if (Model.DownloadRecords.Any())
{
    <table>
        <tr>
            <th>Abfrage</th>
            <th>Zeitraum von</th>
            <th>Zeitraum bis</th>
            <th style="text-align:right">Download</th>
        </tr>
        @foreach (var downloadRecord in Model.DownloadRecords)
        {
            <tr>
                <td>@downloadRecord.Selection.DisplayName</td>
                <td>@downloadRecord.TimeRangeStart.ToString("d")</td>
                <td>@downloadRecord.TimeRangeEnd.ToString("d")</td>
                <td style="text-align:right">
                    @Html.ActionLink(Strings.CsvLabel, "RedownloadRecord", "Home", new {recordId = downloadRecord.Id, format = DownloadFormat.CSV}, null)
                    |
                    @Html.ActionLink(Strings.ExcelLabel, "RedownloadRecord", "Home", new {recordId = downloadRecord.Id, format = DownloadFormat.Excel}, null)
                </td>
            </tr>
        }
    </table>
}
else
{
    <div>
        @Strings.NoDownloadsPlaceholder
    </div>
}

编辑:添加了整个视图代码

1 个答案:

答案 0 :(得分:1)

您无法通过ajax调用返回要下载的文件,因此使用@Ajax.ActionLink()不合适。相反,处理第一个表中的链接点击以进行更新数据库中的记录和ajax调用(即表示已下载),并在成功回调中更新第二个表,并使用{{1}下载文件。添加location.href属性以区分表

id

添加一个脚本来处理第一个表中链接的click事件,进行ajax调用以更新数据库中的记录,并在其成功回调中更新第二个表,最后下载该文件。

<table id="assigned">
    <thead> ... add table headings ... </thead>
    <tbody>
        @foreach (var selection in Model.AssignedDatabaseSelections)
        {
            <tr>
                <td>@selection.DisplayName</td>
                <td>
                    @Html.ActionLink(Strings.CsvLabel, "DownloadSelection", "Home", new { selectionId = selection.Id, format = DownloadFormat.CSV }, null)
                    ....
                </td>
            </td>
        </tr>
    }
</table>
<div id="history">
    <table>
        <thead> ... add table headings ... </thead>
        <tbody>
            @foreach (var downloadRecord in Model.DownloadRecords)
            {
                <tr>
                    <td>@downloadRecord.Selection.DisplayName</td>
                    ....
                </tr>
            }
        </tbody>
    </table>
</div>

$('#assigned').on('click', 'a', function(e) { e.preventDefault(); // cancel default redirect var downloadUrl = $(this).attr('href'); var id = $(this).data('id'); var row = $(this).closest('tr'); var url = '@Url.Action("UpdateHistory")'; $.post(url, { id: id }, function(response){ $('#history').html(response); // update the table location.href = downloadUrl; // download file }); }); 方法

的位置
UpdateHistory

[HttpPost] public PartialViewResult UpdateHistory(int id) { // Update the database record to set the flag its been downloaded var model = ... // Generate a collection of the records used to display in the History table return PartialView("_History", model); } 是部分视图,可在主视图中生成第二个表格。