如何使用 ng-Flow 在 ASP.NET 中分块上传文件

2024-01-10

我正在尝试实现 ng-flowhttps://github.com/flowjs/ng-flow用于文件上传。它以块的形式上传文件,我在客户端成功设置了此设置,但我不确定如何在 Web api 方法内处理后端的文件。

  public void Upload()
        {
            //how to handle file?
        }

The request contain the following information enter image description here


这是我想出的 ASP.NET Web API 控制器,用于保存块并组装它们。

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
using System.IO;
using System.Web;
using System.Web.Http;

namespace Api.Controllers
{
    [RoutePrefix("api")]
    public class FlowUploadController : ApiController
    {

        string root = Path.Combine(Path.GetTempPath(), "FlowUpload");

        [Route("flowupload"), AcceptVerbs("GET")]
        public object Upload(
            int flowChunkNumber,
            string flowIdentifier)
        {
            if (ChunkIsHere(flowChunkNumber, flowIdentifier))
            {
                return Request.CreateResponse(HttpStatusCode.OK);
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
        }

        [Route("flowupload"), AcceptVerbs("POST")]
        public async Task<object> Upload()
        {
            // Check if the request contains multipart/form-data.
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }
            if (!Directory.Exists(root)) Directory.CreateDirectory(root);
            var provider = new MultipartFormDataStreamProvider(root);
            try
            {
                await Request.Content.ReadAsMultipartAsync(provider);
                int chunkNumber = Convert.ToInt32(provider.FormData["flowChunkNumber"]);
                int totalChunks = Convert.ToInt32(provider.FormData["flowTotalChunks"]);
                string identifier = provider.FormData["flowIdentifier"];
                string filename = provider.FormData["flowFilename"];
                // Rename generated file
                MultipartFileData chunk = provider.FileData[0]; // Only one file in multipart message
                RenameChunk(chunk, chunkNumber, identifier);
                // Assemble chunks into single file if they're all here
                TryAssembleFile(identifier, totalChunks, filename);
                // Success
                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (System.Exception e)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
            }

        }

        private string GetChunkFileName(int chunkNumber, string identifier)
        {
            return Path.Combine(root, string.Format("{0}_{1}", identifier, chunkNumber.ToString()));
        }

        private void RenameChunk(MultipartFileData chunk, int chunkNumber, string identifier)
        {
            string generatedFileName = chunk.LocalFileName;
            string chunkFileName = GetChunkFileName(chunkNumber, identifier);
            if (File.Exists(chunkFileName)) File.Delete(chunkFileName);
            File.Move(generatedFileName, chunkFileName);

        }

        private string GetFileName(string identifier)
        {
            return Path.Combine(root, identifier);
        }

        private bool ChunkIsHere(int chunkNumber, string identifier)
        {
            string fileName = GetChunkFileName(chunkNumber, identifier);
            return File.Exists(fileName);
        }

        private bool AllChunksAreHere(string identifier, int totalChunks)
        {
            for (int chunkNumber = 1; chunkNumber <= totalChunks; chunkNumber++)
                if (!ChunkIsHere(chunkNumber, identifier)) return false;
            return true;
        }

        private void TryAssembleFile(string identifier, int totalChunks, string filename)
        {
            if (AllChunksAreHere(identifier, totalChunks))
            {
                // Create a single file
                var consolidatedFileName = GetFileName(identifier);
                using (var destStream = File.Create(consolidatedFileName, 15000))
                {
                    for (int chunkNumber = 1; chunkNumber <= totalChunks; chunkNumber++)
                    {
                        var chunkFileName = GetChunkFileName(chunkNumber, identifier);
                        using (var sourceStream = File.OpenRead(chunkFileName))
                        {
                            sourceStream.CopyTo(destStream);
                        }
                    }
                    destStream.Close();
                }
                // Rename consolidated with original name of upload
                filename = Path.GetFileName(filename); // Strip to filename if directory is specified (avoid cross-directory attack)
                string realFileName = Path.Combine(root, filename);
                if (File.Exists(filename)) File.Delete(realFileName);
                File.Move(consolidatedFileName, realFileName);
                // Delete chunk files
                for (int chunkNumber = 1; chunkNumber <= totalChunks; chunkNumber++)
                {
                    var chunkFileName = GetChunkFileName(chunkNumber, identifier);
                    File.Delete(chunkFileName);
                }
            }
        }

    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 ng-Flow 在 ASP.NET 中分块上传文件 的相关文章

  • C# Julian 日期解析器

    我在电子表格中有一个单元格 它是 Excel 中的日期对象 但当它来自 C1 的 xls 类时 它会变成双精度型 类似于 2009 年 1 月 7 日的 39820 0 我读到这是儒略日期格式 有人可以告诉我如何在 C 中将其解析回 Dat
  • 如何让 LinqToSql 将“索引提示”传递给 sql server?

    由于我们不能相信我们的客户会更新 sql server 中的索引统计信息等 因此我们过去不得不使用索引提示 http www sql server performance com tips hints general p1 aspx 由于我
  • Sitecore - 隐藏功能区中的按钮

    我为特定内容项创建了上下文功能区 我有两个按钮 可以将项目 升级 或 降级 到某一类别 该部分只能有一个 是否可以根据某种隐藏代码中的内容状态隐藏其中一个按钮 我了解如何链接到 Click 事件 但我想知道是否有某种加载事件可供自定义功能区
  • 如何获取Winforms窗体标题栏高度的大小?

    因此 如果它是工具窗口或可最小化的表单 我希望能够以编程方式获取其高度 这可能吗 如果是这样怎么办 您可以使用以下方法确定工具窗口和普通表单的标题栏高度 Rectangle screenRectangle this RectangleToS
  • 设置 Form.KeyPreview = true 的缺点?

    我想知道 Form KeyPreview 属性实际上有什么用处 它为什么存在以及将其设置为 true 会带来什么 风险 我想它一定有some负面影响 否则它根本不应该存在 或者至少默认情况下是正确的 EDIT 我很清楚what确实如此 我问
  • .NET“默认行终止符”?

    有什么方法可以弄清楚 NET 使用什么作为其 默认行终止符 例如 StringBuilder AppendLine String 的文档表示 附加指定字符串的副本 后跟默认行终止符 NET 中的几个与文本相关的类引用相同的概念 有什么方法可
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 抛出并保留堆栈跟踪不符合代码分析所描述的预期

    进行代码分析给了我项目 CA2200 CA2200 重新抛出以保留堆栈详细信息 func 重新抛出捕获的异常并将其显式指定为参数 请改用不带参数的 throw 以保留最初引发异常的堆栈位置 我已经实现了该建议 但无论如何我似乎都得到了相同的
  • 为什么 new String("Hello") 在 C# 中无效?

    制作背后的逻辑 原因是什么 String s new String Hello World 在 C 中非法 错误是 string String char 的最佳重载方法匹配有一些无效参数 我对 API 文档不感兴趣 我感兴趣的是为什么这是非
  • 比较已编译的 .NET 程序集?

    有没有什么好的程序可以与编译 NET 程序集进行比较 例如 我有 HelloWorld dll 1 0 0 0 和 HelloWorld dll 2 0 0 0 我想比较差异 我该怎么做 我知道我可以使用 NET Reflector 并使用
  • C# 和匿名对象数组

    这样的表达是什么意思呢 obj DataSource new new Text Silverlight Count 10 Link Tags Silverlight new Text IIS 7 Count 11 Link http iis
  • 自定义代码访问安全属性

    我创建了以下属性 Serializable AttributeUsage AttributeTargets Class AttributeTargets Method AllowMultiple true Inherited true pu
  • 如何计算最低系统要求?

    对于我用 Visual C 编写的应用程序 Testing 不 真的 这就是全部
  • .NET 中是否有内置函数可以对密码进行哈希处理?

    我看到这个问题加密 散列数据库中的纯文本密码 https stackoverflow com questions 287517 encrypting hashing plain text passwords in database 我知道我
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur

随机推荐