细谈 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"] = 1;
hash["errmsg"] = "上传出错";
var file = provider.FileData[0];//provider.FormData
string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
FileInfo fileinfo = new FileInfo(file.LocalFileName);
//最大文件大小
int maxSize = 10000000;
if (fileinfo.Length <= 0)
{
hash["error"] = 1;
hash["errmsg"] = "请选择上传文件。";
}
else if (fileinfo.Length > maxSize)
{
hash["error"] = 1;
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(1).ToLower()) == -1)
{
hash["error"] = 1;
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"] = 0;
hash["errmsg"] = "上传成功";
}
}
return hash;
});
return task;
}

[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"] = 1;
hash["errmsg"] = "上传出错";
var file = provider.FileData[0];//provider.FormData
string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
FileInfo fileinfo = new FileInfo(file.LocalFileName);
//最大文件大小
int maxSize = 10000000;
if (fileinfo.Length <= 0)
{
hash["error"] = 1;
hash["errmsg"] = "请选择上传文件。";
}
else if (fileinfo.Length > maxSize)
{
hash["error"] = 1;
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(1).ToLower()) == -1)
{
hash["error"] = 1;
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"] = 0;
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 变量无法赋值问题的更多相关文章

  1. 细谈 Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题的解决办法!

    在使用Asp.Net Web Api 图片上传接口的时候,到网上找了一些个例子,但大多数找到都是这个版本! [HttpPost] public Task<Hashtable> ImgUpl ...

  2. Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程

    Asp.Net Core Web Api图片上传及MongoDB存储实例教程(一) 图片或者文件上传相信大家在开发中应该都会用到吧,有的时候还要对图片生成缩略图.那么如何在Asp.Net Core W ...

  3. Asp.Net Web Api 图片上传

    public string UploadFile()        {            if (Request.Content.IsMimeMultipartContent())         ...

  4. web前端图片上传(3)--filereader

    这篇文章主要是为了介绍一种文件上传的方式.当然文件中是包含图片的.如果大家仔细看我的第一篇web前端图片上传(1)就会知道,其实也是按照这种方式上传你的,但是由于上次时间比较紧张,没有详细的介绍今天的 ...

  5. java web开发 图片上传功能

    基本思路在于,配置路径,然后用java I/O的api将图片上传到该目录下. String photoPath =    ServletActionContext.getServletContext( ...

  6. web前端图片上传

    图片上传有很多种形式,但是听说ios只能传字符串,所以为了安卓.ios和web能用一个接口上传图片,采用了基于base64 的方法上传图片. 下面是我的html <div class=" ...

  7. Asp.Net Core 3.0 学习3、Web Api 文件上传 Ajax请求以及跨域问题

    1.创建Api项目 我用的是VS2019 Core3.1 .打开Vs2019 创建Asp.Net Core Web应用程序命名CoreWebApi 创建选择API 在Controller文件夹下面添加 ...

  8. Uploadify 结合 Web API 2 上传问题

    最近使用jQuery.Uploadify和Web API配合来做上传,碰到问题,还木有办法解决,记录一下: 环境:jQuery 1.10.2,Uploadify 3.2.1,SWFObject 2.2 ...

  9. asp.net web api 文件上传

    1正确的做法 public class AvaterController : BaseApiController { [HttpPost] public async Task<IHttpActi ...

随机推荐

  1. RabbitMQ (两)工作队列

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/37620057 本系列教程主要来自于官网新手教程的翻译,然后自己进行了部分的改动与 ...

  2. Oracle语句优化1

    Oracle语句优化1 优化就是选择最有效的方法来执行SQL语句.Oracle优化器选择它认为最有效的     方法来执行SQL语句.         1. IS   NULL和IS   NOT   ...

  3. Hadoop之——CentOS构造ssh否password登录注意事项

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46388809 前提配置:使用root登录改动配置文件:/etc/ssh/sshd_ ...

  4. 远程数据client交换器

    不太繁忙的文本. 要被写入

  5. 变焦控制ZoomControls

    在安卓的webview中有这个点击放大缩小button,当时就在想如何实现那种效果,弄一个两个图标的ImageButton.但感觉又有些麻烦,昨天看疯狂安卓书.无意中发现另一个 ZoomButtons ...

  6. java_Eclipse主题颜色配置+全屏

    http://www.eclipsecolorthemes.org/ 这个是主题的网站. 在Eclipse里, File->Import->General->Preferences- ...

  7. Asp.net MVC + EF + Spring.Net 项目实践(一)

    准备用几篇文章来做一个MVC的例子,为了给新同事做参考,也为自己做个知识储备. 首先,用VS2013创建一个空白解决方案StudentManageSystem,然后添加一个MVC应用程序(可参考ASP ...

  8. 随记一个C的时间加减

    //Centos6 x86_64 #include <time.h>#include <stdio.h>#include <string.h>#include &l ...

  9. JS全选功能代码优化

    原文:JS全选功能代码优化 JS全选功能代码优化 最近在看javascript MVC那本书,也感觉到自己写的代码也并不优雅,所以一直在想 用另一种模式来编写JS代码,所以针对之前的简单的JS全选功能 ...

  10. IOS中UIDatePicker

    UIDatePicker 1.常见属性 /* 样式 UIDatePickerModeTime,时间 UIDatePickerModeDate,日期 UIDatePickerModeDateAndTim ...