Windows Phone7 實現文件上傳

openkk 12年前發布 | 29K 次閱讀 Windows Phone開發 移動開發 Windows Phone

在基于Http協議的Post請求中,Content-type為application/x-www-form-urlencoded的傳輸只能傳送非文件的數據。

如果想用Http的Post方法來上傳數據及文件,需要實現Content-type為multipart/form-data類型的協議程序。

下面是參考了StackOverflow網站上的一個例子,實現了關于客戶端上傳文件的功能類,代碼如下:

using System;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.IO;

namespace ZDWorks.ZDClock.Cloud
{
    /// <summary>
    /// 文件類型數據的內容參數
    /// </summary>
    public class FileParameter
    {
        // 文件內容
        public byte[] File { get; set; }
        // 文件名
        public string FileName { get; set; }
        // 文件內容類型
        public string ContentType { get; set; }

        public FileParameter(byte[] file) : this(file, null) { }

        public FileParameter(byte[] file, string filename) : this(file, filename, null) { }

        public FileParameter(byte[] file, string filename, string contentType)
        {
            File = file;
            FileName = filename;
            ContentType = contentType;
        }
    }

    /// <summary>
    /// 數據與文件http請求
    /// </summary>
    public class HttpMultipartFormRequest
    {
        #region Data Members

        private readonly Encoding DefaultEncoding = Encoding.UTF8;
        private ResponseCallback m_Callback;
        private byte[] m_FormData;

        #endregion

        #region Constructor

        public HttpMultipartFormRequest()
        { 
        }

        #endregion

        #region Delegate

        public delegate void ResponseCallback(string msg);

        #endregion

        public void AsyncHttpRequest(string postUri, Dictionary<string, object> postParameters, ResponseCallback callback)
        {
            // 隨機序列,用作防止服務器無法識別數據的起始位置
            string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
            // 設置contentType
            string contentType = "multipart/form-data; boundary=" + formDataBoundary;
            // 將數據轉換為byte[]格式
            m_FormData = GetMultipartFormData(postParameters, formDataBoundary);
            // 回調函數
            m_Callback = callback;

            // 創建http對象
            HttpWebRequest request = HttpWebRequest.CreateHttp(new Uri(postUri));
            // 設為post請求
            request.Method = "POST";
            request.ContentType = contentType;
            // 請求寫入數據流
            request.BeginGetRequestStream(GetRequestStreamCallback, request);
        }

        private void GetRequestStreamCallback(IAsyncResult ar)
        {
            HttpWebRequest request = ar.AsyncState as HttpWebRequest;
            using (var postStream = request.EndGetRequestStream(ar))
            {
                postStream.Write(m_FormData, 0, m_FormData.Length);
                postStream.Close();
            }
            request.BeginGetResponse(GetResponseCallback, request);
        }

        private void GetResponseCallback(IAsyncResult ar)
        {
            // 處理Post請求返回的消息
            try
            {
                HttpWebRequest request = ar.AsyncState as HttpWebRequest;
                HttpWebResponse response = request.EndGetResponse(ar) as HttpWebResponse;
                using (var stream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(stream);
                    string msg = reader.ReadToEnd();

                    if (m_Callback != null)
                    {
                        m_Callback(msg);
                    }
                }
            }
            catch (Exception e)
            {
                string a = e.ToString();
                if (m_Callback != null)
                {
                    m_Callback(string.Empty);
                }
            }
        }

        private byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
        {
            Stream formDataStream = new MemoryStream();
            bool needsCLRF = false;

            foreach (var param in postParameters)
            {
                if (needsCLRF)
                {
                    formDataStream.Write(DefaultEncoding.GetBytes("\r\n"), 0, DefaultEncoding.GetByteCount("\r\n"));
                }
                needsCLRF = true;

                if (param.Value is FileParameter)
                {
                    FileParameter fileToUpload = (FileParameter)param.Value;

                    string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
                        boundary,
                        param.Key,
                        fileToUpload.FileName ?? param.Key,
                        fileToUpload.ContentType ?? "application/octet-stream");

                    // 將與文件相關的header數據寫到stream中
                    formDataStream.Write(DefaultEncoding.GetBytes(header), 0, DefaultEncoding.GetByteCount(header));
                    // 將文件數據直接寫到stream中
                    formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
                }
                else
                {
                    string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                        boundary,
                        param.Key,
                        param.Value);
                    formDataStream.Write(DefaultEncoding.GetBytes(postData), 0, DefaultEncoding.GetByteCount(postData));
                }
            }

            string tailEnd = "\r\n--" + boundary + "--\r\n";
            formDataStream.Write(DefaultEncoding.GetBytes(tailEnd), 0, DefaultEncoding.GetByteCount(tailEnd));

            // 將Stream數據轉換為byte[]格式
            formDataStream.Position = 0;
            byte[] formData = new byte[formDataStream.Length];
            formDataStream.Read(formData, 0, formData.Length);
            formDataStream.Close();

            return formData;
        }
    }
}
轉自:http://blog.csdn.net/moxiaomomo/article/details/7902064

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!