Windows Phone7 實現檔案上傳

l_serein發表於2013-01-25

在基於Http協議的Post請求中,Content-type為application/x-www-form-urlencoded的傳輸只能傳送非檔案的資料。

如果想用Http的Post方法來上傳資料及檔案,需要實現Content-type為multipart/form-data型別的協議程式。

下面是參考了StackOverflow網站上的一個例子,實現了關於客戶端上傳檔案的功能類,程式碼如下:

001 using System;
002 using System.Net;
003 using System.Text;
004 using System.Collections.Generic;
005 using System.IO;
006  
007 namespace ZDWorks.ZDClock.Cloud
008 {
009     /// <summary>
010     /// 檔案型別資料的內容引數
011     /// </summary>
012     public class FileParameter
013     {
014         // 檔案內容
015         public byte[] File { getset; }
016         // 檔名
017         public string FileName { getset; }
018         // 檔案內容型別
019         public string ContentType { getset; }
020  
021         public FileParameter(byte[] file) : this(file, null) { }
022  
023         public FileParameter(byte[] file, string filename) : this(file, filename,null) { }
024  
025         public FileParameter(byte[] file, string filename, string contentType)
026         {
027             File = file;
028             FileName = filename;
029             ContentType = contentType;
030         }
031     }
032  
033     /// <summary>
034     /// 資料與檔案http請求
035     /// </summary>
036     public class HttpMultipartFormRequest
037     {
038         #region Data Members
039  
040         private readonly Encoding DefaultEncoding = Encoding.UTF8;
041         private ResponseCallback m_Callback;
042         private byte[] m_FormData;
043  
044         #endregion
045  
046         #region Constructor
047  
048         public HttpMultipartFormRequest()
049         {
050         }
051  
052         #endregion
053  
054         #region Delegate
055  
056         public delegate void ResponseCallback(string msg);
057  
058         #endregion
059  
060         public void AsyncHttpRequest(string postUri, Dictionary<stringobject> postParameters, ResponseCallback callback)
061         {
062             // 隨機序列,用作防止伺服器無法識別資料的起始位置
063             string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
064             // 設定contentType
065             string contentType = "multipart/form-data; boundary=" + formDataBoundary;
066             // 將資料轉換為byte[]格式
067             m_FormData = GetMultipartFormData(postParameters, formDataBoundary);
068             // 回撥函式
069             m_Callback = callback;
070  
071             // 建立http物件
072             HttpWebRequest request = HttpWebRequest.CreateHttp(new Uri(postUri));
073             // 設為post請求
074             request.Method = "POST";
075             request.ContentType = contentType;
076             // 請求寫入資料流
077             request.BeginGetRequestStream(GetRequestStreamCallback, request);
078         }
079  
080         private void GetRequestStreamCallback(IAsyncResult ar)
081         {
082             HttpWebRequest request = ar.AsyncState as HttpWebRequest;
083             using (var postStream = request.EndGetRequestStream(ar))
084             {
085                 postStream.Write(m_FormData, 0, m_FormData.Length);
086                 postStream.Close();
087             }
088             request.BeginGetResponse(GetResponseCallback, request);
089         }
090  
091         private void GetResponseCallback(IAsyncResult ar)
092         {
093             // 處理Post請求返回的訊息
094             try
095             {
096                 HttpWebRequest request = ar.AsyncState as HttpWebRequest;
097                 HttpWebResponse response = request.EndGetResponse(ar) asHttpWebResponse;
098                 using (var stream = response.GetResponseStream())
099                 {
100                     StreamReader reader = new StreamReader(stream);
101                     string msg = reader.ReadToEnd();
102  
103                     if (m_Callback != null)
104                     {
105                         m_Callback(msg);
106                     }
107                 }
108             }
109             catch (Exception e)
110             {
111                 string a = e.ToString();
112                 if (m_Callback != null)
113                 {
114                     m_Callback(string.Empty);
115                 }
116             }
117         }
118  
119         private byte[] GetMultipartFormData(Dictionary<stringobject> postParameters, string boundary)
120         {
121             Stream formDataStream = new MemoryStream();
122             bool needsCLRF = false;
123  
124             foreach (var param in postParameters)
125             {
126                 if (needsCLRF)
127                 {
128                     formDataStream.Write(DefaultEncoding.GetBytes("\r\n"), 0, DefaultEncoding.GetByteCount("\r\n"));
129                 }
130                 needsCLRF = true;
131  
132                 if (param.Value is FileParameter)
133                 {
134                     FileParameter fileToUpload = (FileParameter)param.Value;
135  
136                     string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
137                         boundary,
138                         param.Key,
139                         fileToUpload.FileName ?? param.Key,
140                         fileToUpload.ContentType ?? "application/octet-stream");
141  
142                     // 將與檔案相關的header資料寫到stream中
143                     formDataStream.Write(DefaultEncoding.GetBytes(header), 0, DefaultEncoding.GetByteCount(header));
144                     // 將檔案資料直接寫到stream中
145                     formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
146                 }
147                 else
148                 {
149                     string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
150                         boundary,
151                         param.Key,
152                         param.Value);
153                     formDataStream.Write(DefaultEncoding.GetBytes(postData), 0, DefaultEncoding.GetByteCount(postData));
154                 }
155             }
156  
157             string tailEnd = "\r\n--" + boundary + "--\r\n";
158             formDataStream.Write(DefaultEncoding.GetBytes(tailEnd), 0, DefaultEncoding.GetByteCount(tailEnd));
159  
160             // 將Stream資料轉換為byte[]格式
161             formDataStream.Position = 0;
162             byte[] formData = new byte[formDataStream.Length];
163             formDataStream.Read(formData, 0, formData.Length);
164             formDataStream.Close();
165  
166             return formData;
167         }
168     }
169 }
轉自:http://blog.csdn.net/moxiaomomo/article/details/7902064

相關文章