我有一个名为ExportPagePartial的asp.net core MVC局部视图,它允许用户从系统中导出一个页面并下载它。在HttpGet控制器动作中,我显示了部分视图(作为一个Modal弹出)来获取用户输入。
模态弹出式窗口
<a class="dropdown-item" asp-action="ExportPagePartial" asp-route-userId="@Model.UserId" asp-route-businessAccountId="@Model.BusinessAccountId" asp-route-projectId="@Model.ProjectId" asp-route-pageId="@Model.PageId" data-toggle="modal" data-target="#ModalPlaceholder" title="Export page."><i class="fas fa-cloud-download-alt"></i> Export</a>
控制器获取动作
[HttpGet]
public IActionResult ExportPagePartial(string userId, string businessAccountId, string projectId, string pageId)
{
ExportPageViewModel model = new ExportPageViewModel()
{
// Set properties
};
return PartialView(nameof(ExportPagePartial), model);
}
一旦用户从Modal弹出的部分视图中点击Export按钮(这是一个表单提交动作),下面的HTTPPost动作就会被正确调用。在这个动作中,我必须从Web Api中获取文件,然后通过浏览器下载,然而在下载完成后,我想关闭部分视图。一旦下载完成,部分视图仍然可见。
返回动作从来没有工作,部分模态弹出视图也没有关闭。return RedirectToAction(nameof(BlahRedirectAction))。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ExportPagePartial(ExportPageViewModel model)
{
// Call Web API to get the file
string downloadUrl = "blah_blah_url";
using (HttpResponseMessage httpResponse = await WebApiClient.HttpClient.PostAsJsonAsync(downloadUrl, unprotectedExportInput))
{
if (!httpResponse.IsSuccessStatusCode)
{
throw new InvalidOperationException(await httpResponse.Content.ReadAsStringAsync());
}
// Download the file now.
ActionContext actionContext = new ActionContext(HttpContext, ControllerContext.RouteData, ControllerContext.ActionDescriptor, ModelState);
FileStreamResult fileContent = File(await httpResponse.Content.ReadAsStreamAsync(), httpResponse.Content.Headers.ContentType.MediaType, httpResponse.Content.Headers.ContentDisposition.FileName);
await fileContent.ExecuteResultAsync(actionContext);
}
// Redirect to main pain
// The view never redirects and partial view is still visible
return RedirectToAction(nameof(BlahRedirectAction));
}
fileContent.ExecuteResultAsync(actionContext)。
这是因为当你下载文件时。ExportPagePartial
已经确定了回流,不会再进行。RedirectToAction
.
我建议你把触发ExportPagePartial的post方法改为 ajax
来实现,这样你就可以成功执行ExportPagePartial,并在该方法后,将页面重定向到你想要的js中。
下面是我根据你的代码制作的完整的演示代码。
public class ExportTestController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult ExportPagePartial(string userId, string businessAccountId, string projectId, string pageId)
{
ExportPageViewModel model = new ExportPageViewModel()
{
Id = 1,
Gender = "male",
Name = "aaa",
Number = "1231244"
};
return PartialView(nameof(ExportPagePartial), model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ExportPagePartial(ExportPageViewModel model)
{
// Call Web API to get the file
string downloadUrl = "blah_blah_url";
using (HttpResponseMessage httpResponse = await WebApiClient.HttpClient.PostAsJsonAsync(downloadUrl, unprotectedExportInput))
{
if (!httpResponse.IsSuccessStatusCode)
{
throw new InvalidOperationException(await httpResponse.Content.ReadAsStringAsync());
}
// Download the file now.
ActionContext actionContext = new ActionContext(HttpContext, ControllerContext.RouteData, ControllerContext.ActionDescriptor, ModelState);
FileStreamResult fileContent = File(await httpResponse.Content.ReadAsStreamAsync(), httpResponse.Content.Headers.ContentType.MediaType, httpResponse.Content.Headers.ContentDisposition.FileName);
await fileContent.ExecuteResultAsync(actionContext);
}
// Redirect to main pain
// The view never redirects and partial view is still visible
return RedirectToAction(nameof(BlahRedirectAction));
}
Index.cshtml:
@{
ViewData["Title"] = "Index";
Layout = null;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script>
$(function () {
$("a").click(function () {
var route = $(this).attr("href");
$('#partial').load(route);
})
$("form").submit(function () {
$.ajax({
url: $("form").attr('action'),
type: 'Post',
data: $("form").serializeArray(),
success: function () {
//$("#ModalPlaceholder").hide();
window.location.href = "/ExportTest/BlahRedirectAction";
}
});
})
})
</script>
<a class="dropdown-item" asp-action="ExportPagePartial"
asp-route-userId="1" asp-route-businessAccountId="1"
asp-route-projectId="1" asp-route-pageId="1"
data-toggle="modal" data-target="#ModalPlaceholder" title="Export page."><i class="fas fa-cloud-download-alt"></i> Export</a>
<div class="modal fade" id="ModalPlaceholder" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<form asp-action="ExportPagePartial" method="post">
<div id="partial">
</div>
</form>
</div>
ExportPagePartial.cshtml:
@model ExportPageViewModel
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label asp-for="Id" class="control-label">@Model.Id</label>
<input asp-for="Id" class="form-control" hidden />
</div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Gender" class="control-label"></label>
<input asp-for="Gender" class="form-control" />
<span asp-validation-for="Gender" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Number" class="control-label"></label>
<input asp-for="Number" class="form-control" />
<span asp-validation-for="Number" class="text-danger"></span>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" >Save changes</button>
</div>
</div>
</div>
这是测试结果。