细谈 Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题的解决办法!
2015-04-17 14:50
786 查看
在使用Asp.Net Web Api 图片上传接口的时候,到网上找了一些个例子,但大多数找到都是这个版本!
View Code
如果只是上传,简单用是可以的,但是你可能不会发现有什么问题。但如果你在 Request.Content.ReadAsMultipartAsync(provider) .ContinueWith 延时Task任务 里面赋值一个变量,你就会发现 始终赋值不上,不信你可以试试。
例子 如下:
上面的得出的结果 : filename = " Not set " ;
【 注意如下结论 】
经测试发现如下结论,在执行 Request.Content.ReadAsMultipartAsync(provider) . ContinueWith 异步延时任务的时候,先不会被立即执行。
等待 return 结束之后才会被执行。这也就是为什么返回的总是: " Not set " 。
经过几天的摸索测试,在StackOverFlow上找到了一个解决的办法如下:
改造后就变成了这样,真的太棒了!
相关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
[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; }
View Code
如果只是上传,简单用是可以的,但是你可能不会发现有什么问题。但如果你在 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 变量无法赋值问题
- ie9中无法使用fckeditor上传图片,解决办法
- 在IE7关闭窗口,上传图片无法预览,window.status无效问题解决办法
- [转]在IE7关闭窗口,上传图片无法预览,window.status无效问题解决办法
- 在IE7关闭窗口,上传图片无法预览,window.status无效问题解决办法
- [转]在IE7关闭窗口,上传图片无法预览,window.status无效问题解决办法
- fckedirot使用 及与struts2整合图片上传问题的解决办法
- 在IE7/IE8 关闭窗口,上传图片无法预览,window.status无效问题解决办法
- Django模板无法使用perms变量问题解决办法详解
- ASP.Net项目的所有的变量突然无法赋值的问题解决办法
- 记录java上传图片第一时间无法展示的问题以及解决办法
- HTML5异步上传图片(支持预览和进度条),使用其他按钮触发file onclick事件,解决某些浏览器无法触发的问题
- 【问题解决】使用Strust2文件上传图片无法显示
- 解决关于Wordpress在SAE平台上无法上传图片的问题
- 使用PLSQL Developer时,“ORA-12154: TNS:无法解析指定的连接标识符”问题的一个解决办法
- Shell编程中使用管道循环中无法改变外部变量的解决办法
- JSP页面中使用JSTL标签出现无法解析问题解决办法
- 解决使用EclipseDebug进入到JDK源码无法查看运行时变量的问题