文件下载后如何重定向ASP.NET Core MVC局部视图?

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

我有一个名为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> &nbsp; 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));
 }
asp.net asp.net-mvc asp.net-core-mvc partial-views
1个回答
1
投票

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> &nbsp; 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">&times;</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> 

这是测试结果。

enter image description here

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