zoukankan      html  css  js  c++  java
  • 细谈 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; 
    }
    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

    在寂寞的日子里沉淀自己,在程序的日子里找到自己,我为梦想而坚持!

    如果对你有重要帮助,可以打赏一下!


  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    108. Convert Sorted Array to Binary Search Tree
    111. Minimum Depth of Binary Tree
    49. Group Anagrams
    使用MALTAB标定实践记录
    442. Find All Duplicates in an Array
    522. Longest Uncommon Subsequence II
    354. Russian Doll Envelopes
    opencv 小任务3 灰度直方图
    opencv 小任务2 灰度
  • 原文地址:https://www.cnblogs.com/Kummy/p/3553799.html
Copyright © 2011-2022 走看看