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

  1. [HttpPost]
  2. public Task<Hashtable> ImgUpload()
  3. {
  4. // 检查是否是 multipart/form-data
  5. if (!Request.Content.IsMimeMultipartContent("form-data"))
  6. throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
  7. //文件保存目录路径
  8. string SaveTempPath = "~/SayPlaces/" + "/SayPic/SayPicTemp/";
  9. String dirTempPath = HttpContext.Current.Server.MapPath(SaveTempPath);
  10. // 设置上传目录
  11. var provider = new MultipartFormDataStreamProvider(dirTempPath);
  12. //var queryp = Request.GetQueryNameValuePairs();//获得查询字符串的键值集合
  13. var task = Request.Content.ReadAsMultipartAsync(provider).
  14. ContinueWith<Hashtable>(o =>
  15. {
  16. Hashtable hash = new Hashtable();
  17. hash["error"] = ;
  18. hash["errmsg"] = "上传出错";
  19. var file = provider.FileData[];//provider.FormData
  20. string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
  21. FileInfo fileinfo = new FileInfo(file.LocalFileName);
  22. //最大文件大小
  23. int maxSize = ;
  24. if (fileinfo.Length <= )
  25. {
  26. hash["error"] = ;
  27. hash["errmsg"] = "请选择上传文件。";
  28. }
  29. else if (fileinfo.Length > maxSize)
  30. {
  31. hash["error"] = ;
  32. hash["errmsg"] = "上传文件大小超过限制。";
  33. }
  34. else
  35. {
  36. string fileExt = orfilename.Substring(orfilename.LastIndexOf('.'));
  37. //定义允许上传的文件扩展名
  38. String fileTypes = "gif,jpg,jpeg,png,bmp";
  39. if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(fileTypes.Split(','), fileExt.Substring().ToLower()) == -)
  40. {
  41. hash["error"] = ;
  42. hash["errmsg"] = "上传文件扩展名是不允许的扩展名。";
  43. }
  44. else
  45. {
  46. String ymd = DateTime.Now.ToString("yyyyMMdd", System.Globalization.DateTimeFormatInfo.InvariantInfo);
  47. String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", System.Globalization.DateTimeFormatInfo.InvariantInfo);
  48. fileinfo.CopyTo(Path.Combine(dirTempPath, newFileName + fileExt), true);
  49. fileinfo.Delete();
  50. hash["error"] = ;
  51. hash["errmsg"] = "上传成功";
  52. }
  53. }
  54. return hash;
  55. });
  56. return task;
  57. }

如果只是上传,简单用是可以的,但是你可能不会发现有什么问题。但如果你在 Request.Content.ReadAsMultipartAsync(provider).ContinueWith 延时Task任务 里面赋值一个变量,你就会发现 始终赋值不上,不信你可以试试。

例子 如下:

  1. public string UploadFile()
  2. {
  3. if (Request.Content.IsMimeMultipartContent())
  4. {
  5. //Save file
  6. MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/Files"));string filename = "Not set";
  7.  
  8. Request.Content.ReadAsMultipartAsync(provider).ContinueWith(o =>
  9. {
  10. //File name
  11. filename = "Set success";
  12. }, TaskScheduler.FromCurrentSynchronizationContext());
  13.  
  14. return filename;
  15. }
  16. else
  17. {
  18. return "Invalid.";
  19. }
  20. }

上面的得出的结果filename = "Not set" ;

注意如下结论

经测试发现如下结论,在执行 Request.Content.ReadAsMultipartAsync(provider).ContinueWith 异步延时任务的时候,先不会被立即执行。

等待 return 结束之后才会被执行。这也就是为什么返回的总是: "Not set"

经过几天的摸索测试,在StackOverFlow上找到了一个解决的办法如下:

  1. IEnumerable<HttpContent> parts = null;
  2. Task.Factory
  3. .StartNew(() => parts = Request.Content.ReadAsMultipartAsync().Result.Contents,
  4. CancellationToken.None,
  5. TaskCreationOptions.LongRunning, // guarantees separate thread
  6. TaskScheduler.Default)
  7. .Wait();

改造后就变成了这样,真的太棒了!

  1. public string UploadFile()
  2. {
  3. if (Request.Content.IsMimeMultipartContent())
  4. {
  5. //Save file
  6. MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("/UploadUser/"));
  7.  
  8. string filename = "Not set";
  9.  
  10. IEnumerable<HttpContent> parts = null;
  11. Task.Factory
  12. .StartNew(() =>
  13. {
  14. parts = Request.Content.ReadAsMultipartAsync(provider).Result.Contents;
  15. filename = "Set Success";
  16. },
  17. CancellationToken.None,
  18. TaskCreationOptions.LongRunning, // guarantees separate thread
  19. TaskScheduler.Default)
  20. .Wait();
  21.  
  22. return filename;
  23. }
  24. else
  25. {
  26. return "Invalid.";
  27. }
  28. }

相关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 变量无法赋值问题

    细谈 Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题的解决办法!   在使用Asp.Net Web Api 图片上传接口的时候,到网上找了一些个例子,但大多数找 ...

  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. Web App 图片上传编辑器

    使用cropper.jqueryUpload插件.Jquery.src-dataurl-canvas-blob文件. @{ ViewBag.Title = "更新头像"; Layo ...

随机推荐

  1. git 查看某个文件的修改记录

    有几种方式, (1)如果是在linux环境下,比如centos,ubuntu之类的,建议安装tig命令 炒鸡好用,tig后面可以跟文件或者文件夹,比如: (1.1)tig  dir_name (1.2 ...

  2. bat/cmd将命令执行的结果赋值给变量

    比如我想把git代码的commitid获取以后加到文件夹上来标记文件夹中的包是哪个git 节点构建得到的. git 命令是git rev-parse --short HEAD 再linux系统下,只需 ...

  3. Node.JS 项目打包 JXCore

    哈哈,又回来了 当你开发完成了Node.JS项目,你应该需要打包发行吧 好,JXCore就是干这个的啦! 嗯,可能你会这样来安装 1. curl http://jxcore.com/xil.sh | ...

  4. iOS 设计模式-NSNotificationCenter 通知中心

    通知介绍 每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的消息通信 任何一个对象都可以向通知中心发布通知(NSNotification),描述 ...

  5. Reveal使用

    本人手机是7.1的,reveal2.0以后不支持8.0以下,没办法,这里只能使用reveal1.6. 这里提醒一下,reveal2.0以后libReavel.lib改名了,. https://reve ...

  6. Lua 与 OC 相互调用

    本文主要讲如何完成lua和object-c的相互调用.       lua是一种脚本语言,可以方便的移植到各种宿主语言中,并且可以支持热更新,在游戏开发中也能当做主要的语言来编写游戏的逻辑,但是要接入 ...

  7. RMAN备份策略与异机恢复一例

    实验环境: A机器(生产用途):RHEL 6.5 + Oracle 11.2.0.4 + IP Address 192.168.1.11 B机器(备机用途):RHEL 6.5 + Oracle 11. ...

  8. uvm设计分析——factory

    uvm的factory机制,通过实例一个static类型default factory,并且通过宏将所有例化extend出来的object,component register到该factory的内部 ...

  9. C语言---变量与函数

    一个C程序是由一个或多个程序模块组成的,每一个程序模块作为一个源程序文件,一个源程序文件是一个编译单元. 源程序文件分为库函数和用户自己定义的函数,以及有参函数.无参函数. 函数调用的过程: 1) 定 ...

  10. maven 知识

    1. maven 环境配置 Maven 3.3 要求 JDK 1.7 或以上   Maven 3.2 要求 JDK 1.6 或以上   Maven 3.0/3.1 要求 JDK 1.5 或以上 2. ...