• asp.net6 blazor 文件上传


    微软在asp.net6中给blazor新增了一个IJSStreamReference的接口。

    我们今天的所有内容,都要依赖这个接口,因为它可以把流直接传到c#中,这样我们就可以做很多的骚操作了。


    今天我们来做一个简单的文件上传,这里以bootstrapblazor中新的CherryMarkdown组件为例。


    首先,CherryMarkdown本身就支持文件上传处理,所以我们可以直接拿到js中的file,这里就不用考虑获取文件的方式了。


    这里我们直接用window来保存这个file对象,这样操作应该是最简单的。

                        fileUpload(file, callback) {
                            window.files = {};
                            window.files[0] = file;
                            obj.invokeMethodAsync('Upload', {
                                fileName: file.name,
                                fileSize: file.size,
                                contentType: file.type,
                                lastModified: new Date(file.lastModified).toISOString(),
                            }).then(data => {
                                if (data !== "") {
                                    callback(data);
                                }
                            })
                        },

    这里我们定义了window.files[0]为我们要上传的文件内容。

    然后再写一个方法来返回这个window.files[0]

    export function bb_cherry_markdown_file(){
        return window.files[0];
    }

    这样,我们的js部分就搞定了,无需webapi,也无需其他的支持。


    下面我们来看c#部分,也是相当简单。

    首先我们写一个Upload方法来接收文件上传的请求。

        /// <summary>
        /// 文件上传回调
        /// </summary>
        /// <param name="uploadFile"></param>
        [JSInvokable]
        public async Task<string> Upload(CherryMarkdownUploadFile uploadFile)
        {
            var stream = await Module.InvokeAsync<IJSStreamReference>("bb_cherry_markdown_file");
            var data = await stream.OpenReadStreamAsync();
            uploadFile.UploadStream = data;
            if (OnFileUpload == null)
            {
                return "";
            }
            return await OnFileUpload.Invoke(uploadFile);
        }

    这里的CherryMarkdownUploadFile如下:

    /// <summary>
    /// 文件信息
    /// </summary>
    public class CherryMarkdownUploadFile
    {
        /// <summary>
        /// 文件名
        /// </summary>
        public string? FileName { get; set; }
    
        /// <summary>
        /// 文件大小
        /// </summary>
        public long FileSize { get; set; }
    
        /// <summary>
        /// 最后修改日期
        /// </summary>
        public string? LastModified { get; set; }
    
        /// <summary>
        /// 文件类型
        /// </summary>
        public string? ContentType { get; set; }
    
        /// <summary>
        /// 上传的文件流
        /// </summary>
        public Stream? UploadStream { get; set; }
    
        /// <summary>
        /// 返回码,0为成功,非0失败
        /// </summary>
        public int Code { get; set; }
    
        /// <summary>
        /// 错误信息
        /// </summary>
        public string? Error { get; set; }
    
        /// <summary>
        /// 保存到文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task<bool> SaveToFile(string fileName, CancellationToken token = default)
        {
            var ret = false;
            if (UploadStream != null)
            {
                // 文件保护,如果文件存在则先删除
                if (System.IO.File.Exists(fileName))
                {
                    try
                    {
                        System.IO.File.Delete(fileName);
                    }
                    catch (Exception ex)
                    {
                        Code = 1002;
                        Error = ex.Message;
                    }
                }
    
                var folder = Path.GetDirectoryName(fileName);
                if (!string.IsNullOrEmpty(folder) && !Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }
    
                if (Code == 0)
                {
                    using var uploadFile = File.OpenWrite(fileName);
    
                    try
                    {
                        // 打开文件流
                        var stream = UploadStream;
    
                        var buffer = new byte[4 * 1096];
                        int bytesRead = 0;
    
                        // 开始读取文件
                        while ((bytesRead = await stream.ReadAsync(buffer, token)) > 0)
                        {
                            await uploadFile.WriteAsync(buffer.AsMemory(0, bytesRead), token);
    
                        }
                        ret = true;
                    }
                    catch (Exception ex)
                    {
                        Code = 1003;
                        Error = ex.Message;
                    }
                }
            }
            return ret;
        }
    
    }

    可以用来接收js中的

    obj.invokeMethodAsync('Upload', {
                                fileName: file.name,
                                fileSize: file.size,
                                contentType: file.type,
                                lastModified: new Date(file.lastModified).toISOString(),
                            }).then(data => {
                                if (data !== "") {
                                    callback(data);
                                }
                            })

    并且有一个SaveToFile方法可以将流保存为文件。

    然后就是最关键的这行代码:

    var stream = await Module.InvokeAsync<IJSStreamReference>("bb_cherry_markdown_file");

    我们调用刚刚js中的bb_cherry_markdown_file方法来获取浏览器中的window.files[0],就可以返回一个stream,然后我们就可以结合CherryMarkdownUploadFile来将文件保存。

  • 相关阅读:
    【Python自动化测试】mock模块基本使用介绍
    关于C# HttpClient 的用法及相关问题的解决方法
    聊聊spring的TransactionalEventListener
    SpringCloud——微服务
    【考研复试】计算机专业考研复试英语常见问题四(优缺点/观点/观念篇)
    py 打开多个页面
    什么是兼容性测试? 重要性是什么?
    【Python】进阶学习:pandas--groupby()用法详解
    十二、Sequential
    基于点云的深度学习方法综述
  • 原文地址:https://www.cnblogs.com/j4587698/p/16301706.html