细谈 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 ...
随机推荐
- CentOS6.5安装Tomcat8.0
1.首先从官网下载最新的安装包 http://tomcat.apache.org/ apache-tomcat-8.0.20.tar.gz 2.上传安装包到 /usr/local/mypackage ...
- Selenium基础知识(二)鼠标操作
一.鼠标操作 这个需要使用webdriver下的ActionChains类,这个类是操作鼠标操作的: from selenium.webdriver import ActionChains 鼠标操作可 ...
- 日期条控件 DateFieldControl
日期条控件 书:163 <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns ...
- python+selenium入门
from selenium import webdriver打开浏览器 driver = webdriver.Chrome() 打开网页 driver.get("http://www.bai ...
- 关于 CGI,Fastcgi和php-fpm 理解
首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者. web server(比如说nginx)只是内容的分发者.比如,如果请求/index.h ...
- java微信小程序调用支付接口
简介:微信小程序支付这里的坑还是有的,所以提醒各位在编写的一定要注意!!! 1.首先呢,你需要准备openid,appid,还有申请微信支付后要设置一个32位的密钥,需要先生成一个sign,得到pre ...
- struts2实现jQuery的异步交互
struts2中jQuery的异步交互有两种方式: 1)是利用构造字符串的方式来实现: 使用该方法主要是在服务器端根据前端的请求,返回一个字符串信息,然后前端的jQuery通过解析该字符串信息得到对应 ...
- RDD、DataFrame、Dataset三者三者之间转换
转化: RDD.DataFrame.Dataset三者有许多共性,有各自适用的场景常常需要在三者之间转换 DataFrame/Dataset转RDD: 这个转换很简单 val rdd1=testDF. ...
- c#如何判断字符串是否含中文
如代码: static bool ContainChinese(string input) { string pattern = "[\u4e00-\u9fbb]"; return ...
- linux命令目录
一.文件和目录.(文件目录的增删改查) ls pwd cd mkdir touch rmdir ln dd rm cp mv nl cat tac more less head tail stat # ...