细谈 Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题的解决办法!
在使用Asp.Net Web Api 图片上传接口的时候,到网上找了一些个例子,但大多数找到都是这个版本!
- [HttpPost]
- public Task<Hashtable> ImgUpload()
- {
- // 检查是否是 multipart/form-data
- if (!Request.Content.IsMimeMultipartContent("form-data"))
- throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
- //文件保存目录路径
- string SaveTempPath = "~/SayPlaces/" + "/SayPic/SayPicTemp/";
- String dirTempPath = HttpContext.Current.Server.MapPath(SaveTempPath);
- // 设置上传目录
- var provider = new MultipartFormDataStreamProvider(dirTempPath);
- //var queryp = Request.GetQueryNameValuePairs();//获得查询字符串的键值集合
- var task = Request.Content.ReadAsMultipartAsync(provider).
- ContinueWith<Hashtable>(o =>
- {
- Hashtable hash = new Hashtable();
- hash["error"] = ;
- hash["errmsg"] = "上传出错";
- var file = provider.FileData[];//provider.FormData
- string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
- FileInfo fileinfo = new FileInfo(file.LocalFileName);
- //最大文件大小
- int maxSize = ;
- if (fileinfo.Length <= )
- {
- hash["error"] = ;
- hash["errmsg"] = "请选择上传文件。";
- }
- else if (fileinfo.Length > maxSize)
- {
- hash["error"] = ;
- hash["errmsg"] = "上传文件大小超过限制。";
- }
- else
- {
- string fileExt = orfilename.Substring(orfilename.LastIndexOf('.'));
- //定义允许上传的文件扩展名
- String fileTypes = "gif,jpg,jpeg,png,bmp";
- if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(fileTypes.Split(','), fileExt.Substring().ToLower()) == -)
- {
- hash["error"] = ;
- hash["errmsg"] = "上传文件扩展名是不允许的扩展名。";
- }
- else
- {
- String ymd = DateTime.Now.ToString("yyyyMMdd", System.Globalization.DateTimeFormatInfo.InvariantInfo);
- String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", System.Globalization.DateTimeFormatInfo.InvariantInfo);
- fileinfo.CopyTo(Path.Combine(dirTempPath, newFileName + fileExt), true);
- fileinfo.Delete();
- hash["error"] = ;
- hash["errmsg"] = "上传成功";
- }
- }
- return hash;
- });
- return task;
- }
如果只是上传,简单用是可以的,但是你可能不会发现有什么问题。但如果你在 Request.Content.ReadAsMultipartAsync(provider).ContinueWith 延时Task任务 里面赋值一个变量,你就会发现 始终赋值不上,不信你可以试试。
例子 如下:
- public string UploadFile()
- {
- if (Request.Content.IsMimeMultipartContent())
- {
- //Save file
- MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/Files"));string filename = "Not set";
- Request.Content.ReadAsMultipartAsync(provider).ContinueWith(o =>
- {
- //File name
- filename = "Set success";
- }, TaskScheduler.FromCurrentSynchronizationContext());
- return filename;
- }
- else
- {
- return "Invalid.";
- }
- }
上面的得出的结果: filename = "Not set" ;
【注意如下结论】
经测试发现如下结论,在执行 Request.Content.ReadAsMultipartAsync(provider).ContinueWith 异步延时任务的时候,先不会被立即执行。
等待 return 结束之后才会被执行。这也就是为什么返回的总是: "Not set" 。
经过几天的摸索测试,在StackOverFlow上找到了一个解决的办法如下:
- IEnumerable<HttpContent> parts = null;
- Task.Factory
- .StartNew(() => parts = Request.Content.ReadAsMultipartAsync().Result.Contents,
- CancellationToken.None,
- TaskCreationOptions.LongRunning, // guarantees separate thread
- TaskScheduler.Default)
- .Wait();
改造后就变成了这样,真的太棒了!
- public string UploadFile()
- {
- if (Request.Content.IsMimeMultipartContent())
- {
- //Save file
- MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("/UploadUser/"));
- string filename = "Not set";
- IEnumerable<HttpContent> parts = null;
- Task.Factory
- .StartNew(() =>
- {
- parts = Request.Content.ReadAsMultipartAsync(provider).Result.Contents;
- filename = "Set Success";
- },
- CancellationToken.None,
- TaskCreationOptions.LongRunning, // guarantees separate thread
- TaskScheduler.Default)
- .Wait();
- return filename;
- }
- else
- {
- return "Invalid.";
- }
- }
相关Task的文章:
http://stackoverflow.com/questions/10502353/task-continuewith-execution-orderTa
http://www.strathweb.com/2012/08/a-guide-to-asynchronous-file-uploads-in-asp-net-web-api-rtm/
StackOverFlow 最终解决方案:
http://stackoverflow.com/questions/15201255/request-content-readasmultipartasync-never-returns
细谈 Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题的解决办法!的更多相关文章
- Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题
细谈 Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题的解决办法! 在使用Asp.Net Web Api 图片上传接口的时候,到网上找了一些个例子,但大多数找 ...
- Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程
Asp.Net Core Web Api图片上传及MongoDB存储实例教程(一) 图片或者文件上传相信大家在开发中应该都会用到吧,有的时候还要对图片生成缩略图.那么如何在Asp.Net Core W ...
- Asp.Net Web Api 图片上传
public string UploadFile() { if (Request.Content.IsMimeMultipartContent()) ...
- web前端图片上传(3)--filereader
这篇文章主要是为了介绍一种文件上传的方式.当然文件中是包含图片的.如果大家仔细看我的第一篇web前端图片上传(1)就会知道,其实也是按照这种方式上传你的,但是由于上次时间比较紧张,没有详细的介绍今天的 ...
- java web开发 图片上传功能
基本思路在于,配置路径,然后用java I/O的api将图片上传到该目录下. String photoPath = ServletActionContext.getServletContext( ...
- web前端图片上传
图片上传有很多种形式,但是听说ios只能传字符串,所以为了安卓.ios和web能用一个接口上传图片,采用了基于base64 的方法上传图片. 下面是我的html <div class=" ...
- Asp.Net Core 3.0 学习3、Web Api 文件上传 Ajax请求以及跨域问题
1.创建Api项目 我用的是VS2019 Core3.1 .打开Vs2019 创建Asp.Net Core Web应用程序命名CoreWebApi 创建选择API 在Controller文件夹下面添加 ...
- Uploadify 结合 Web API 2 上传问题
最近使用jQuery.Uploadify和Web API配合来做上传,碰到问题,还木有办法解决,记录一下: 环境:jQuery 1.10.2,Uploadify 3.2.1,SWFObject 2.2 ...
- Web App 图片上传编辑器
使用cropper.jqueryUpload插件.Jquery.src-dataurl-canvas-blob文件. @{ ViewBag.Title = "更新头像"; Layo ...
随机推荐
- git 查看某个文件的修改记录
有几种方式, (1)如果是在linux环境下,比如centos,ubuntu之类的,建议安装tig命令 炒鸡好用,tig后面可以跟文件或者文件夹,比如: (1.1)tig dir_name (1.2 ...
- bat/cmd将命令执行的结果赋值给变量
比如我想把git代码的commitid获取以后加到文件夹上来标记文件夹中的包是哪个git 节点构建得到的. git 命令是git rev-parse --short HEAD 再linux系统下,只需 ...
- Node.JS 项目打包 JXCore
哈哈,又回来了 当你开发完成了Node.JS项目,你应该需要打包发行吧 好,JXCore就是干这个的啦! 嗯,可能你会这样来安装 1. curl http://jxcore.com/xil.sh | ...
- iOS 设计模式-NSNotificationCenter 通知中心
通知介绍 每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的消息通信 任何一个对象都可以向通知中心发布通知(NSNotification),描述 ...
- Reveal使用
本人手机是7.1的,reveal2.0以后不支持8.0以下,没办法,这里只能使用reveal1.6. 这里提醒一下,reveal2.0以后libReavel.lib改名了,. https://reve ...
- Lua 与 OC 相互调用
本文主要讲如何完成lua和object-c的相互调用. lua是一种脚本语言,可以方便的移植到各种宿主语言中,并且可以支持热更新,在游戏开发中也能当做主要的语言来编写游戏的逻辑,但是要接入 ...
- RMAN备份策略与异机恢复一例
实验环境: A机器(生产用途):RHEL 6.5 + Oracle 11.2.0.4 + IP Address 192.168.1.11 B机器(备机用途):RHEL 6.5 + Oracle 11. ...
- uvm设计分析——factory
uvm的factory机制,通过实例一个static类型default factory,并且通过宏将所有例化extend出来的object,component register到该factory的内部 ...
- C语言---变量与函数
一个C程序是由一个或多个程序模块组成的,每一个程序模块作为一个源程序文件,一个源程序文件是一个编译单元. 源程序文件分为库函数和用户自己定义的函数,以及有参函数.无参函数. 函数调用的过程: 1) 定 ...
- maven 知识
1. maven 环境配置 Maven 3.3 要求 JDK 1.7 或以上 Maven 3.2 要求 JDK 1.6 或以上 Maven 3.0/3.1 要求 JDK 1.5 或以上 2. ...