ASP.NET 服務端接收Multipart/form-data文件

来源:http://www.cnblogs.com/Dewumu/archive/2017/08/24/7422338.html
-Advertisement-
Play Games

在網路編程過程中需要向伺服器上傳文件。 Multipart/form-data是上傳文件的一種方式。 ...


在網路編程過程中需要向伺服器上傳文件。

Multipart/form-data是上傳文件的一種方式。

  1        /// <summary>
  2        /// 上傳工程文件
  3        /// </summary>
  4        /// <returns></returns>
  5         public async Task<HttpResponseMessage> UploadProjectFile()
  6         {
  7                 ProjectFile postData = new ProjectFile();
  8                 IEnumerable<string> stringValues;
  9                 //獲取請求頭文件相關參數
 10                 Request.Headers.TryGetValues("token", out stringValues);
 11                 postData.token = stringValues.FirstOrDefault();
 12 
 13                 Request.Headers.TryGetValues("uid", out stringValues);
 14                 postData.uid = int.Parse(stringValues.FirstOrDefault());
 15 
 16                 Request.Headers.TryGetValues("project_id", out stringValues);
 17                 postData.project_id = int.Parse(stringValues.FirstOrDefault());
 18 
 19                 Request.Headers.TryGetValues("md5", out stringValues);
 20                 postData.md5 = stringValues.FirstOrDefault();
 21 
 22                 Request.Headers.TryGetValues("file_name", out stringValues);
 23                 postData.file_name = stringValues.FirstOrDefault();
 24                //驗證Token
 25                 var result = CheckToken(postData.token);
 26                 if (!result)
 27                 {
 28                     return CreateResponseError(401, "請求拒絕");
 29                 }
 30                 //獲取文件名,這裡的文件名必須帶擴展名
 31                 string fileName = postData.file_name;
 32                 
 33                 int projectId = postData.project_id;
 34                 //獲取應用程式的當前工作目錄
 35                 string rootPath = HostingEnvironment.MapPath("~/");
 36                 //通過Path類的Combine方法可以合併路徑。獲取當前工程文件夾地址
 37                 string directoryPath = Path.Combine(rootPath, "BgerProject", projectId.ToString());
 38                 //創建目錄時如果目錄已存在,則不會重新創建目錄,且不會報錯。創建目錄時會自動創建路徑中各級不存在的目錄。
 39                 Directory.CreateDirectory(directoryPath);
 40                 //獲取當前工程文件地址
 41                 string filePath = Path.Combine(directoryPath, fileName);
 42                 if (Request.Content.IsMimeMultipartContent())
 43                 {
 44                     Dictionary<string, string> dic = new Dictionary<string, string>();
 45                     var provider = new MultipartFormDataMemoryStreamProvider();
 46                     
 47                     await Request.Content.ReadAsMultipartAsync(provider);
 48                     foreach (var item in provider.FileContents)
 49                     {
 50                         //Trace.WriteLine(item.Headers.ContentDisposition.FileName);//獲取上傳文件實際的文件名  
 51                         //Trace.WriteLine("Server file path: " + item.LocalFileName);//獲取上傳文件在服務上預設的文件名  
 52                         var stream = await item.ReadAsStreamAsync();
 53                         if (Path.GetExtension(item.Headers.ContentDisposition.FileName.Replace("\"", "")) == ".mp4")
 54                         {
 55                             //通過正則表達式判斷是視頻還是音頻
 56                             Regex regex = new Regex("voice", RegexOptions.Compiled);
 57                             Match m = regex.Match(item.Headers.ContentDisposition.Name.ToLower());
 58                             if (m.Success)
 59                             {
 60                                 //音頻直接保存處理
 61                                
 62                                 //判斷是否已存在該音頻
 63                                 if (!File.Exists(filePath))
 64                                 {
 65                                     using (StreamWriter sw = new StreamWriter(filePath))
 66                                     {
 67                                         stream.CopyTo(sw.BaseStream);
 68                                         sw.Flush();
 69                                     }
 70                                 }
 71                             }
 72                             else
 73                             {
 74                                 //視頻進行壓縮處理
 75                                 //保存原片(如果路徑不存在,創建路徑)
 76                                 
 77                                 using (StreamWriter sw = new StreamWriter(filePath))
 78                                 {
 79                                     stream.CopyTo(sw.BaseStream);
 80                                     sw.Flush();
 81                                 }
 82                                 //壓縮並保存上傳的視頻
 83                                 //壓縮後的存放路徑(如果路徑不存在,創建路徑)
 84                                 ////判斷是否已存在該視頻
 85                                 //if (!File.Exists(filePath))
 86                                 //{
 87                                 //    //壓縮保存視頻
 88                                 //    if (!FFMPEGHelper.CreateNewVideo(originalFilePath, filePath))
 89                                 //    {
 90                                 //        continue;
 91                                 //    };
 92                                 //}
 93                             }
 94                         }
 95                         else
 96                         {
 97                             //保存原片(如果路徑不存在,創建路徑)
 98                            
 99                             using (StreamWriter sw = new StreamWriter(filePath))
100                             {
101                                 stream.CopyTo(sw.BaseStream);
102                                 sw.Flush();
103                             }
104                             //壓縮並保存上傳的圖片
105                             //壓縮後的存放路徑(如果路徑不存在,創建路徑)
106                            
107                             ////判斷是否已存在該圖片
108                             //if (!File.Exists(filePath))
109                             //{
110                             //    var pxLimit = 481;
111                             //    //判斷是否需要壓縮
112                             //    System.Drawing.Image iSource = System.Drawing.Image.FromFile(originalFilePath);
113                             //    if (iSource.Width <= pxLimit || iSource.Height <= pxLimit)
114                             //    {
115                             //        //無需壓縮
116                             //        System.IO.File.Copy(originalFilePath, filePath);
117                             //    }
118                             //    else
119                             //    {
120                             //        var min = Math.Min((int)iSource.Width, (int)iSource.Height);
121                             //        if (min > pxLimit)
122                             //        {
123                             //            //縮放倍率
124                             //            var rate = (double)pxLimit / min;
125                             //            var width = (int)Math.Ceiling(rate * (double)iSource.Width);
126                             //            var height = (int)Math.Ceiling(rate * (double)iSource.Height);
127 
128                             //            //壓縮保存圖片
129                             //            if (!ImageHelper.GetPicThumbnail(originalFilePath, filePath, height, width, 100))
130                             //            {
131                             //                continue;
132                             //            };
133                             //        }
134                             //    }
135                             //}
136                         }
137                     }
138                     return CreateResponse("請求成功");
139                     
140                 }
141                 return CreateResponseError(202,"缺少MIME內容");
142             
143         }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Collections.ObjectModel;
 6 using System.Collections.Specialized;
 7 using System.IO;
 8 using System.Net.Http;
 9 using System.Net.Http.Headers;
10 using System.Threading;
11 using System.Threading.Tasks;
12 
13 namespace BgerServer.Models
14 {
15     /// <summary>  
16     /// 與MultipartFormDataStreamProvider對應,但不將文件直接存入指定位置,而是需要自己指定數據流如何保存  
17     /// </summary>  
18     public class MultipartFormDataMemoryStreamProvider : MultipartStreamProvider
19     {
20         private NameValueCollection _formData = new NameValueCollection();
21         private Collection<bool> _isFormData = new Collection<bool>();
22         /// <summary>  
23         /// 獲取文件對應的HttpContent集合,文件如何讀取由實際使用方確定,可以ReadAsByteArrayAsync,也可以ReadAsStreamAsync  
24         /// </summary>  
25         public Collection<HttpContent> FileContents
26         {
27             get
28             {
29                 if (this._isFormData.Count != this.Contents.Count)//兩者總數不一致,認為未執行過必須的Request.Content.ReadAsMultipartAsync(provider)方法  
30                 {
31                     throw new InvalidOperationException("System.Net.Http.HttpContentMultipartExtensions.ReadAsMultipartAsync must be called first!");
32                 }
33                 return new Collection<HttpContent>(this.Contents.Where((ct, idx) => !this._isFormData[idx]).ToList());
34             }
35         }
36         /// <summary>Gets a <see cref="T:System.Collections.Specialized.NameValueCollection" /> of form data passed as part of the multipart form data.</summary>  
37         /// <returns>The <see cref="T:System.Collections.Specialized.NameValueCollection" /> of form data.</returns>  
38         public NameValueCollection FormData
39         {
40             get
41             {
42                 return this._formData;
43             }
44         }
45         public override async Task ExecutePostProcessingAsync()
46         {
47             for (var i = 0; i < this.Contents.Count; i++)
48             {
49                 if (!this._isFormData[i])//非文件  
50                 {
51                     continue;
52                 }
53                 var formContent = this.Contents[i];
54                 ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition;
55                 string formFieldName = UnquoteToken(contentDisposition.Name) ?? string.Empty;
56                 string formFieldValue = await formContent.ReadAsStringAsync();
57                 this.FormData.Add(formFieldName, formFieldValue);
58             }
59         }
60         public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
61         {
62             if (parent == null)
63             {
64                 throw new ArgumentNullException("parent");
65             }
66             if (headers == null)
67             {
68                 throw new ArgumentNullException("headers");
69             }
70             ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;
71             if (contentDisposition == null)
72             {
73                 throw new InvalidOperationException("Content-Disposition is null");
74             }
75             this._isFormData.Add(string.IsNullOrEmpty(contentDisposition.FileName));
76             return new MemoryStream();
77         }
78         /// <summary>  
79         /// 複製自 System.Net.Http.FormattingUtilities 下同名方法,因為該類為internal,不能在其它命名空間下被調用  
80         /// </summary>  
81         /// <param name="token"></param>  
82         /// <returns></returns>  
83         private static string UnquoteToken(string token)
84         {
85             if (string.IsNullOrWhiteSpace(token))
86             {
87                 return token;
88             }
89             if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
90             {
91                 return token.Substring(1, token.Length - 2);
92             }
93             return token;
94         }
95     }
96 }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、Oracle VirtualBox安裝Linux7.0全屏設置 1. 點擊菜單欄 設備 –> 分配光碟機 –> 選擇一個虛擬光碟,找到VirtualBox安裝目錄下的VBoxGuestAdditions.iso,載入此鏡像。2. 啟動Linux系統並用root身份登入系統3. 執行掛載命令,將虛擬 ...
  • 參考了兩種方法: 1. 解決fatal: unable to connect to github.com問題 http://blog.csdn.net/greenqingqingws/article/details/11808745原因:需要用https才能讀到數據解決方法:輸入命令git conf ...
  • 有話要說 為什麼要用Linux?要用Linux的原因太多,想說說不完啊。 如果你說用Linux只是為了裝逼,那證明你真的還很菜。不排除有裝逼了因素,那也只占非常少的比例,可以忽略不計。 我們反問一下,為什麼不用Linux呢?回答無非就是:沒有圖像界面、操作太複雜、和我以前的使用習慣不一樣、學習新的系 ...
  • 添加PPA: 1、首先進入ubuntu系統,system—>administration—>update manager—>setting,在軟體源界面,點擊other software 標簽頁,點擊左下角的add,將獲得的PPA地址粘貼進來。 2、也可以在終端輸入,sudo gedit /etc/ ...
  • 本節課程,需要完成擴增子分析解讀1質控 實驗設計 雙端序列合併 先看一下擴增子分析的整體流程,從下向上逐層分析 分析前準備 # 進入工作目錄 cd example_PE250 上一節回顧:我們拿到了雙端數據,進行了質控、並對實驗設計進行了填寫和檢查、最後將雙端數據合併為單個文件進行下游分析。 接下來 ...
  • 對值類型和引用類型的誤解 (引用類型存儲在堆上,值類型存儲在棧上) 對值類型和引用類型的誤解 (引用類型存儲在堆上,值類型存儲在棧上) 在學習C#基礎篇幅的時候總是逃不掉值類型和引用類型,很多新手包括我以前對它的理解也只是停留在"引用類型存儲在堆上,值類型存儲在棧上". 這個誤區主要歸咎於我們根本沒 ...
  • 第 9 章:常用的設計模式 9.1 聚合組件 考慮為常用的特性域提供聚合組件。 要用聚合組件來對高層的概念(物理對象)進行建模,而不是對系統級的任務進行建模。 要讓聚合組件的名字與眾所周知的系統實體相對應,比如 MessageQueue、Process 或 EventLog,這樣就能使類型更加引人註 ...
  • 為什麼有這種需求, 原因是這樣的, 公司有一個Java的web項目,在另一臺伺服器A上,最近老闆一時興起,想把他合併到這台穩定點的伺服器B上,伺服器B上使用IIS來寄宿asp.net 網站, 怎麼辦呢,硬著頭皮上吧,在網上找各種解決方案: 解決方案一:isapi_redirect 這個方法按照方法試 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...