【问题标题】:How to redirect a ASP.NET Core MVC partial view after file download文件下载后如何重定向 ASP.NET Core MVC 部分视图
【发布时间】:2020-09-06 06:29:12
【问题描述】:

我有一个名为 ExportPagePartial 的 asp.net 核心 MVC 部分视图,它允许用户从系统中导出页面并下载它。在 HttpGet 控制器操作中,我显示部分视图(作为模态弹出窗口)以获取用户输入。

模态弹出窗口

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

一旦用户从模态弹出部分视图(这是一个表单提交操作)中点击导出按钮,就会正确调用以下 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));
 }

【问题讨论】:

  • 局部视图以什么形式呈现,类似于模态弹出?能否提供全面的代码供我们参考?
  • @YongqingYu 是的,部分视图显示为模式弹出窗口,我更新了描述以包含更多详细信息。

标签: asp.net asp.net-mvc asp.net-core-mvc partial-views


【解决方案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> 

这是测试结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多