Asp.net 更新局部视图并下载文件
Asp.net update a partial view and download a file
我有一个网站,其中包含下载列表和已下载文件的历史记录列表。
当我单击一个时,我希望开始下载所选文件并将新项目添加到历史记录中。
目前下载有效:
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)
现在我的问题是,要刷新历史记录,我必须 return 部分视图。但是因为我已经 return 一个文件作为 ActionResult,所以我也不能 return 部分视图。
我尝试了一种使用 Ajax.ActionLink 并为 OnSuccess 添加 AjaxOption 的方法,以便在下载成功后调用第二个控制器 return 局部视图。但不知何故,我的 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>
}
编辑:添加了整个视图代码
您不能 return 通过 ajax 调用下载文件,因此使用 @Ajax.ActionLink()
不是 suitable。相反,在第一个 table 中处理您的链接点击并 ajax 调用更新数据库中的记录(即指示其已下载),并在成功回调中更新第二个table,并使用location.href
下载文件。添加一个id
属性来区分tables
<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>
并在第一个 table 中添加一个脚本来处理链接的点击事件,进行 ajax 调用以更新数据库中的记录,并在其成功回调中更新第二个table,终于下载文件了。
$('#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
是在您的主视图中生成第二个 table 的局部视图。
我有一个网站,其中包含下载列表和已下载文件的历史记录列表。 当我单击一个时,我希望开始下载所选文件并将新项目添加到历史记录中。 目前下载有效:
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)
现在我的问题是,要刷新历史记录,我必须 return 部分视图。但是因为我已经 return 一个文件作为 ActionResult,所以我也不能 return 部分视图。
我尝试了一种使用 Ajax.ActionLink 并为 OnSuccess 添加 AjaxOption 的方法,以便在下载成功后调用第二个控制器 return 局部视图。但不知何故,我的 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>
}
编辑:添加了整个视图代码
您不能 return 通过 ajax 调用下载文件,因此使用 @Ajax.ActionLink()
不是 suitable。相反,在第一个 table 中处理您的链接点击并 ajax 调用更新数据库中的记录(即指示其已下载),并在成功回调中更新第二个table,并使用location.href
下载文件。添加一个id
属性来区分tables
<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>
并在第一个 table 中添加一个脚本来处理链接的点击事件,进行 ajax 调用以更新数据库中的记录,并在其成功回调中更新第二个table,终于下载文件了。
$('#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
是在您的主视图中生成第二个 table 的局部视图。