今天在研究WebAPI的上传与下载,作为Rest的框架,更多是面向资源,就其本身来说,是不会涉及也不应该涉及到大文件的处理,具体多大呢,也就是ASP.NET的限值2G。

ASP.NET的pipeline对于上传文件一般的处理流程是接收到文件,放到内存中,我们也一般只处理后续的流程,例如存入硬盘等等。

目前想象的一个场景是上传一个大文件,后续处理可能有多种。如果并发数过多,肯定会造成内存溢出,所以参考资料与琢磨,搞定了这个问题。

但是场景本身是有一定问题的,这纯属个人爱好在玩,真实场景来说文件不宜过大,不是专门处理大文件的服务器与协议,无非就是用流的方式,但是大文件传输使用流采用可靠协议是最好的,可靠不是指TCP的可靠,而是指在如果断开后,后续的处理,例如断点。

如果是HTTP的断点,那就只有自己写了。

一、配置文件修改

不多说,这个必须的。

   <system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="2147483647"/>
</system.web>
    <security>
<requestFiltering >
<requestLimits maxAllowedContentLength="2147483647" ></requestLimits>
</requestFiltering>
</security>

二、扩展主机缓存Policy

这是微软预留的接口,作为扩展,让用户自己关闭主机是否缓冲,也就是正常流程中将上传文件的内容存入内存的动作

public class NoBufferPolicySelector : WebHostBufferPolicySelector
{
public override bool UseBufferedInputStream(object hostContext)
{
var context = hostContext as HttpContextBase; if (context != null)
{
if (context.Request.HttpMethod == HttpMethod.Post.ToString() && context.Request.ContentLength >)
return false;
} return true;
}

还有个动作就是要去注册它

         public static void Register(HttpConfiguration config)
{
// Web API 配置和服务 // Web API 路由
config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
); GlobalConfiguration.Configuration.Services.Replace(typeof(IHostBufferPolicySelector), new NoBufferPolicySelector()); }

三、想怎么玩儿怎么玩儿

上传的代码,大家都懂的

 [RoutePrefix("test")]
public class UploadController : ApiController
{
[Route("upload")]
[HttpPost]
public Task<IEnumerable<FileDesc>> Post()
{
var folderName = "uploads";
var PATH = HttpContext.Current.Server.MapPath("~/" + folderName);
var rootUrl = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, String.Empty);
if (Request.Content.IsMimeMultipartContent())
{
var streamProvider = new CustomMultipartFormDataStreamProvider(PATH);
var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<IEnumerable<FileDesc>>(t =>
{ if (t.IsFaulted || t.IsCanceled)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
} var fileInfo = streamProvider.FileData.Select(i =>
{
var info = new FileInfo(i.LocalFileName);
return new FileDesc(info.Name, rootUrl + "/" + folderName + "/" + info.Name, info.Length / );
});
return fileInfo;
}); return task;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
} public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public CustomMultipartFormDataStreamProvider(string path)
: base(path)
{ } public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
{
var name = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? headers.ContentDisposition.FileName : "NoName";
return name.Replace("\"", string.Empty);
}
}

MultipartFormDataStreamProvider

还有各种Provider,这样我们就可以有很多种处理方式,去掉WebAPI自带的Buffer,我们自己来处理。

MultipartFormDataRemoteStreamProvider 例如这个Provider,是抽象类,需要自己继承,设想如果我们要把这个上传的文件传到另外的地方去,例如Azure上,我们是不是可以直接架设管道,用流的方式。

下次介绍Provider。

最后还是上图吧,without picture I say ge hair?

准备工作,要上传的文件,才装了系统,就用这个吧

700多MB够了吧,还要怎样?

准备客户端,用网页比较方便,直接看进度

<h2>API Upload</h2>
<form name="apiForm" method="post" enctype="multipart/form-data" action="http://localhost:15068/test/upload">
<div>
<label for="apifiles">Select a File</label>
<input name="apifiles" type="file" />
</div>
<div>
<input type="submit" value="Upload" />
</div>
</form>

那就开始吧

至于内存的占用,既然是流,就不用多说了。不会有很大起伏的,就不贴图了,已经占了很大版面了。

PS:在学习的过程中,还遇到另外一种解决方案,是否还记得ASP.NET中接收上传文件的SaveAS方法,是的,用这个方法的主人也是可以接收文件的,它会干一个有趣的事情,不用内存作为Buffer,而是用硬盘,并且IIS在关闭或者隔一段时间后会干掉这个硬盘Buffer,后续的流程还是一样。对了,这是在IIS上测试的,本地宿主没试过。

WebAPI上传大文件的更多相关文章

  1. Asp.Net上传大文件带进度条swfupload

    Asp.Net基于swfupload上传大文件带进度条百分比显示,漂亮大气上档次,大文件无压力,先看效果 一.上传效果图 1.上传前界面:图片不喜欢可以自己换 2.上传中界面:百分比显示 3.上传后返 ...

  2. 日常采坑:.NetCore上传大文件

    一..NetCore上传大文件 .NetCore3.1 webapi 本地测试上传时,遇到一个坑,大点的文件直接失败,根本不走控制器方法. 二.大文件上传配置 IFormFile方式,vs IIS E ...

  3. [Asp.net]Uploadify上传大文件,Http error 404 解决方案

    引言 之前使用Uploadify做了一个上传图片并预览的功能,今天在项目中,要使用该插件上传大文件.之前弄过上传图片的demo,就使用该demo进行测试.可以查看我的这篇文章:[Asp.net]Upl ...

  4. php 上传大文件配置upload_max_filesize和post_max_size选项

    php 上传大文件配置upload_max_filesize和post_max_size选项 (2014-04-29 14:42:11) 转载▼ 标签: php.ini upload _files[f ...

  5. PHP上传大文件 分割文件上传

    最近遇到这么个情况,需要将一些大的文件上传到服务器,我现在拥有的权限是只能在一个网页版的文件管理系统来进行操作,可以解压,可以压缩,当然也可以用它来在线编辑.php文件. 文件有40M左右,但是服务器 ...

  6. ASP.NET上传大文件的问题

    原文:http://www.cnblogs.com/wolf-sun/p/3657241.html?utm_source=tuicool&utm_medium=referral 引言 之前使用 ...

  7. php 上传大文件主要涉及配置upload_max_filesize和post_max_size两个选项

    php 上传大文件主要涉及配置 upload_max_filesize 和post_max_size两个选项   今天在做上传的时候出现一个非常怪的问题,有时候表单提交可以获取到值,有时候就获取不到了 ...

  8. SWFUpload上传大文件(暂时用用,真正用的时候还是要改的)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. PHP上传大文件和处理大数据

    1. 上传大文件 /* 以1.5M/秒的速度写入文件,防止一次过写入文件过大导致服务器出错(chy/20150327) */ $is_large_file = false; if( strlen($x ...

随机推荐

  1. svn 使用(一个)

    一个. 安装svn  server(操作系统centos) yum install subversion 通过 subversion -v 如果成功安装命令来查看 温馨提示不承担任何subversio ...

  2. 重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础

    原文:重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础 [源码下载] 重新想象 Windows 8 Store Apps (9) - 控件之 Sc ...

  3. The practice program of C on point

    //字符反向排列 //vision 1.2 #include<stdio.h> void reverse_string( char *str ) { char *string;//第一个字 ...

  4. 发布Ubuntu/Linux系统cache,增加可用内存空间

    桌面Ubuntu总内存4G,但free只有内存有100M 重视top命令检查看到真正的能力free内存.以下是真正的内存使用情况的看法有一个命令. watch -n 1 cat /proc/memin ...

  5. testlink于smarty配置和使用

    于testlink于,采用smarty首先配置. 一般在过程化的编程中.创建一个smarty.inc.php的文件来配置Smarty的信息,其它文件引入就可以,目的是为了不改动smarty.class ...

  6. 高质量c c++编程

    第1章 文件结构 每一个C++/C程序通常分为两个文件.一个文件用于保存程序的声明(declaration),称为头文件.还有一个文件用于保存程序的实现(implementation),称为定义(de ...

  7. android最新的工具DateHelper

    最新的工具DateHelper 实用程序类,.的天数来获得一个给定的月份.过了几天去习惯或.周.一个月.日期等.. 代码例如以下: import android.annotation.Suppress ...

  8. C++类实现最大数的输出

    Description 判断整数的大小,输入n个数,找出最大的数并输出. Input 有多组测试实例,输入n,并输入n个数. Output 输出的最大的数,每个输出结果占一行. Sample Inpu ...

  9. 【课程分享】基于plusgantt的项目管理系统实战开发(Spring3+JDBC+RMI的架构、自己定义工作流)

    基于plusgantt的项目管理系统实战开发(Spring3+JDBC+RMI的架构.自己定义工作流) 课程讲师:张弘 课程分类:Java 适合人群:中级 课时数量:37课时 用到技术:Spring  ...

  10. TI C66x DSP 系统events及其应用 - 5.8(ISTP)

    中断服务表指针ISTP(Interrupt Service Table Pointer)位置寄存器用于定位的中断服务例程,那ISTP去哪里找要运行的程序,ISTP(当中的ISTB字段)就是指向IST表 ...