如何使用 asp.net core 2.0 Razor 页面执行下载操作

Posted

技术标签:

【中文标题】如何使用 asp.net core 2.0 Razor 页面执行下载操作【英文标题】:How to perform Download Operation using asp.net core 2.0 Razor Page 【发布时间】:2019-06-25 21:43:25 【问题描述】:

我正在开发文档管理系统,我已成功完成上传删除文件,但我无法执行从数据库下载操作,我是 Razor Pages 的新手,所以如果有人帮助我,将不胜感激。下面是关于我的项目的更多详细信息。

这是我的 Index.cshtml

<div>    
    <table class="table " style="background-color:lightskyblue;" >
        <thead style="font-weight:bold ;color:white;background-color:black;margin-right:-50px;padding-right:80px;">
            <tr  style="background-color:darkblue;color:white;">
                <th>
                    @Html.DisplayNameFor(model => model.Schedule[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Schedule[0].UploadDT)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Schedule[0].PublicScheduleSize)
                </th>
                @*<th class="text-center">
                @Html.DisplayNameFor(model => model.Schedule[0].PrivateScheduleSize)
            </th>*@
                <th class="text-center">Operations</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Schedule)
            
                <tr style="font-weight:bold">
                    <td>
                        @Html.DisplayFor(modelItem => item.Title)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.UploadDT)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.PublicScheduleSize)
                    </td>
                    
                        <td style="margin-left:-60px;">
                            @*<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>*@
                            <a asp-page="./Delete" asp-route-id="@item.ID" class="btn btn-danger glyphicon glyphicon-trash" role="button">Delete</a>
                        </td >
                        <td >
                            <a asp-page="./Download" download="item.UploadDT" asp-route-id="@item.ID" class="btn btn-primary btn-sm glyphicon glyphicon-download-alt " role="button">Download</a>
                        </td>
                    
                </tr>
            
        </tbody>
    </table>
</div>

这是 PageModel(代码隐藏)

namespace DMS.Pages.Schedules

    public class IndexModel : PageModel
    
        private readonly DMS.Models.DatabaseContext _context;

        public IndexModel(DMS.Models.DatabaseContext context)
        
            _context = context;
        

        [BindProperty]
        public FileUpload FileUpload  get; set; 

        public IList<Schedule> Schedule  get; private set; 

        public async Task OnGetAsync()
        
            Schedule = await _context.Schedule.AsNoTracking().ToListAsync();
        

        public async Task<IActionResult> OnPostAsync()
        
            if (!ModelState.IsValid)
            
                Schedule = await _context.Schedule.AsNoTracking().ToListAsync();
                return Page();
            
            var publicScheduleData = await FileHelpers.ProcessFormFile(FileUpload.UploadPublicSchedule, ModelState);
            FileHelpers.ProcessFormFile(FileUpload.UploadPrivateSchedule, ModelState);

            ProcessFormFile method

            if (!ModelState.IsValid)
            
                Schedule = await _context.Schedule.AsNoTracking().ToListAsync();
                return Page();
            
            var schedule = new Schedule()
            
                PublicSchedule = publicScheduleData,
                PublicScheduleSize = FileUpload.UploadPublicSchedule.Length,
                 FileUpload.UploadPrivateSchedule.Length,
                Title = FileUpload.Title,
                UploadDT = DateTime.UtcNow
            ;
            _context.Schedule.Add(schedule);
            await _context.SaveChangesAsync();
            return RedirectToPage("./Index");
        
    

【问题讨论】:

你需要添加文件的路径,你可以指定下载链接在哪里,例如&lt;a href="https://www.example.com/CV.pdf" target="_blank" &gt;Download CV&lt;/a&gt; 我完全不知道如何编写下载操作的代码,所以请你给我这个操作的全貌。这是我的下载link button&lt;a asp-page="./Download" download="item.UploadDT" asp-route-id="@item.ID" class="btn btn-primary btn-sm glyphicon glyphicon-download-alt " role="button"&gt;Download&lt;/a&gt; 我想从数据库执行下载 我已经在答案中发布了链接。请看一看。 【参考方案1】:

您的代码很难解析,但似乎最终您将文件作为 blob 存储在数据库表中。一般来说,您需要一个从数据库中检索此数据并将其作为FileResult 返回的操作:

public OnDownloadGetAsync(int scheduleId)

    var schedule = await _context.Set<Schedule>().FindAsync(scheduleId);
    if (schedule == null)
        return NotFound();

    return File(schedule.PublicSchedule, schedule.PublicScheduleType);

File 的第二个参数是 mime 类型(即text/csvapplication/vnd.excelapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet 等)。如果您知道它始终是相同类型的文件,则可以对其进行硬编码,但理想情况下,您也应该将其保存在数据库中(这就是为什么我“创建”了一个 PublicScheduleType 属性来保存它)。您显然需要修改您的上传代码以保持上传文件的内容类型。

无论如何,像 excel 电子表格之类的东西都应该强制下载,但默认情况下会将文件作为“内联”传递,或者尝试在浏览器中显示它。如果您想始终强制下载,您可以向File 提供第三个参数,带有文件名:

return File(schedule.PublicSchedule, schedule.PublicScheduleType, "schedule.xlsx");

设置完成后,您只需链接到此处理程序:

<a asp-page="Index" asp-handler="Download" asp-route-scheduleId="@schedule.Id">Download</a>

【讨论】:

以上是关于如何使用 asp.net core 2.0 Razor 页面执行下载操作的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core 2.0 中根据路由配置服务身份验证

如何使用 Url.Action 在 asp.net core 2.0 razor 页面中传递多个操作

如何将 UserManager 注入 ASP.NET Core 2.0 中的另一个服务

如何从 ASP.NET Core 2.0 中的自定义中间件请求身份验证

ASP.NET Core 2.0 Razor 页面使用 AddMvcCore() 而不是 AddMvc()

如何在 Visual Studio 2017 Web Proj ASP.NET Core 2.0 中禁用 Https