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

问题描述 投票:0回答:1

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

    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>
}

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

asp.net asp.net-mvc-4
1个回答
1
投票

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

<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>

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

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

_History.cshtml是一个局部视图,在主视图中生成第二个表。

© www.soinside.com 2019 - 2024. All rights reserved.