C# Net6 Ant Design of Blazor + WebApi实现文件上传与下载

0、开发环境

  • Visual Studio 2022
  • 基于net6
  • Ant Design Blazor

1、在Visual Studio 2022中安装AntDesign模版

dotnet new --install AntDesign.Templates

详情请参阅Ant Design Blazor官网

2、在Visual Studio 2022中创建Ant Design Pro Blazor App项目

创建项目时选择Ant Design Pro Blazor App,如下图:
在这里插入图片描述

3、在Ant Design Blazor项目中开启Web Api支持

在修改Startup.cs,以支持对Web Api的支持

1、ConfigureServices方法中增加services.AddControllers();
2、Configure方法中增加endpoints.MapControllers();

详细代码如下:

namespace WebSiteApp
{
    
    
    public class Startup
    {
    
    
        public Startup(IConfiguration configuration)
        {
    
    
            Configuration = configuration;
        }

        public IConfiguration Configuration {
    
     get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
    
    
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddAntDesign();
            services.AddScoped(sp => new HttpClient
            {
    
    
                BaseAddress = new Uri(sp.GetService<NavigationManager>().BaseUri)
            });
            services.Configure<ProSettings>(Configuration.GetSection("ProSettings"));
            
            services.AddControllers();          //增加对WebApi支持
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
    
    
            if (env.IsDevelopment())
            {
    
    
                app.UseDeveloperExceptionPage();
            }
            else
            {
    
    
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            
            //app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();


            app.UseEndpoints(endpoints =>
            {
    
    
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
                endpoints.MapControllers();                 //增加对WebApi支持
            });
        }
    }
}

4、在项目中增加Controllers目录和控制器类

在项目中增加Controllers目录,并在此目录下增加控制器类FilesController.cs实现文件上传下载API,代码如下:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;

namespace WebConfigSiteApp.Controller
{
    
    
    [ApiController]
    [Route("/api/file")]
    public class FilesController : ControllerBase
    {
    
    
        private IWebHostEnvironment env;

        public FilesController(IWebHostEnvironment env)
        {
    
    
            this.env = env;
        }

        [HttpPost, Route("upload")]
        public ResultModel UploadFile([FromForm] IFormCollection formCollection)
        {
    
    
            ResultModel result = new ResultModel();
            result.Message = "success";
            result.Code = 0;
            result.Url = "/api/file/download";

            try
            {
    
    
                string uploadPath = System.IO.Path.Combine(env.ContentRootPath, "upload");
                if (!System.IO.Directory.Exists(uploadPath))
                {
    
    
                    System.IO.Directory.CreateDirectory(uploadPath);
                }

                FormFileCollection fileCollection = (FormFileCollection)formCollection.Files;
                foreach (IFormFile file in fileCollection)
                {
    
    
                    string filePath = System.IO.Path.Combine(uploadPath, Wongoing.Common.Global.BackupFileName);
                    Console.WriteLine(filePath);
                    if (System.IO.File.Exists(filePath))
                    {
    
    
                        System.IO.File.Delete(filePath);
                    }
                    using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
                    {
    
    
                        file.CopyTo(fs);
                        fs.Flush();
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
    
    
                result.Code = 100;
                result.Message = $"文件上传失败:{
      
      ex.Message}!";
                Wongoing.Log.LoggingService<FilesController>.Instance.Error($"文件上传失败:{
      
      ex.Message}", ex);
            }
            return result;
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        [HttpGet, Route("download")]
        [ProducesResponseType(typeof(FileResult), (int)HttpStatusCode.OK)]
        public FileResult Download()
        {
    
    
            try
            {
    
    
                string filePath = System.IO.Path.Combine(this.env.ContentRootPath, "upload", Wongoing.Common.Global.BackupFileName);
                Stream stream = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
                FileStreamResult actionresult = new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"));
                actionresult.FileDownloadName = Wongoing.Common.Global.BackupFileName;
                return actionresult;
            }
            catch (Exception ex)
            {
    
    
                Wongoing.Log.LoggingService<FilesController>.Instance.Error($"文件下载失败:{
      
      ex.Message}", ex);
                return null;
            }
        }

    }

    public class ResultModel
    {
    
    
        public int Code {
    
     get; set; }
        public string Message {
    
     get; set; }
        public string Url {
    
     get; set; }
    }
}

1、为了获取当前站点的物理路径,此类通过构造方法注入了IWebHostEnvironment对象env,env.ContentRootPath表示当前站点根目录的物理路径。
2、Ant Design Blazor Upload组件的Action对应的文件上传接口参数类型为[FromForm] IFormCollection。
3、实现文件下载的API方法可以通过返回Microsoft.AspNetCore.Mvc.FileResult实现。

5、使用Ant Design Blazor Upload组件开发上传的UI页面

在项目中新增一个razor组件以实现文件上传,代码如下:

@namespace WebSiteApp.Pages.Sys
@page "/sys/sysbackup"

<PageContainer>
    <Breadcrumb>
        <Breadcrumb>
            <BreadcrumbItem>首页</BreadcrumbItem>
            <BreadcrumbItem>系统</BreadcrumbItem>
            <BreadcrumbItem>系统备份</BreadcrumbItem>
        </Breadcrumb>
    </Breadcrumb>
    <Content>
        <span style="color:#FF0000">通过此功能实现对配置的备份和恢复!</span>
    </Content>
    <ChildContent>
        <Card Title="系统备份">
            <Row Gutter="16">
                <AntDesign.Col Xl="new EmbeddedProperty{Span = 4}"
                                   Lg="new EmbeddedProperty{Span = 4}"
                                   Md="new EmbeddedProperty{Span = 4}"
                                   Sm="4">
                    <Button Type="@ButtonType.Primary" Icon="copy" OnClick="DoBackup">系统配置备份</Button>
                </AntDesign.Col>
                <AntDesign.Col Xl="new EmbeddedProperty{Span = 4}"
                                   Lg="new EmbeddedProperty{Span = 4}"
                                   Md="new EmbeddedProperty{Span = 4}"
                                   Sm="4" Style="padding-top:8px;">
                    <a href="/api/file/download" target="_blank" class="btn btn-primary" style='display:@(_disabledDownload ? "none": "block");'>下载备份文件</a>
                </AntDesign.Col>
            </Row>
        </Card>
        <Card Title="系统恢复">
            <Row Gutter="16">
                <AntDesign.Col Xl="new EmbeddedProperty{Span = 4}"
                                   Lg="new EmbeddedProperty{Span = 4}"
                                   Md="new EmbeddedProperty{Span = 4}"
                                   Sm="4">
                    <Upload Name="files"
                            Action="/api/file/upload"
                            FileList="fileList"
                            BeforeUpload="BeforeUpload"
                            OnSingleCompleted="OnSingleCompleted">
                        <Button Type="@ButtonType.Primary" Icon="upload">
                            <span>上传备份的文件</span>
                        </Button>
                    </Upload>
                </AntDesign.Col>
                <AntDesign.Col Xl="new EmbeddedProperty{Span = 4}"
                                   Lg="new EmbeddedProperty{Span = 4}"
                                   Md="new EmbeddedProperty{Span = 4}"
                                   Sm="4">
                    <Button Type="@ButtonType.Primary" Icon="rollback" Disabled="@_disabledRecover" OnClick="DoRecover">执行配置恢复</Button>
                </AntDesign.Col>
            </Row>
        </Card>
    </ChildContent>
</PageContainer>

@code {
    RenderFragment icon = @<Icon Type="question-circle" Theme="outline"></Icon>;
}

1、Upload组件的Action属性指定文件上传接口(对应Controllers/FilesController.cs中的UploadFile的路由),在通过Upload组件操作文件上传时,会自动调用Action属性指定的Web Api。
2、下载文件,只需在a标签的href属性执行文件下载接口的访问路径就可,例:<a href=“/api/file/download” target=“_blank”>文件下载</a>

猜你喜欢

转载自blog.csdn.net/zlbdmm/article/details/125140950