苦苦搞了半個通宵才搞定的直接使用Sliverlight將文件PUT到阿里雲OSS


為了公司的項目,小的我各種折騰啊,不過高興的是實現了Silverlight直接提交至阿里雲OSS的文件上傳,文件上傳再也不用通過服務器中轉了。

研究SDK發現還有個Node-oss.js,但還沒進行測試。哪天搞一下。成功的話再搞上來。。。

明天還得研究基於ActionScript 2.0/3.0直接上傳至阿里雲OSS。有得搞了。。。不廢話了,把Silverlight上傳OSS的代碼貼這里,也許大家很多人需要吧。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Net.Browser;
using System.Threading;
using System.Security.Cryptography;
using System.Text;
using SilverlightAliOSSUpload.Common;

namespace SilverlightAliOSSUpload
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
        byte[] buffer = null;
        string accessKeyId = "Access Key ID";
        string accessKeySecret = "Access Key Secret";
        string fileName = string.Empty;

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            if (dialog.ShowDialog() == true)
            {
                try
                {
                    DateTime dt = DateTime.Now;

                    fileName = dialog.File.Name;

                    WebHeaderCollection collection = new WebHeaderCollection();

                    buffer = new byte[dialog.File.Length];

                    using (Stream stream = dialog.File.OpenRead())
                    {
                        stream.Read(buffer, 0, buffer.Length);
                    }

                    collection[HttpRequestHeader.ContentMd5] = ICryptography.GetMD5(buffer).ToUpper();

                    // PUT\n[Content-MD5]\n\n[GMT Date]\n/[BucketName]/[FileName]
                    HMACSHA1 sha = new HMACSHA1();

                    sha.Key = Encoding.UTF8.GetBytes(accessKeySecret.ToCharArray());

                    // 這里值得說一下,是OSS最丫的垃圾的地方。這里面的簽名和URL簽名都必須使用Expires時間,也就是要指定過期時間,我這里是10分鍾后過期
                    // 就這么一行,調了四個多小時。FUCK
                    byte[] hashBuffer = Encoding.UTF8.GetBytes(string.Format("PUT\n{0}\n\n{1}\n/Bucket/{2}", ICryptography.GetMD5(buffer), Convert.ToInt64(DateTimeToUTC(dt.AddMinutes(10))),
                          fileName).ToCharArray());

                    string hash = Convert.ToBase64String(sha.ComputeHash(hashBuffer));

                    // 因為Silverlight的WebRequest不能創建PUT和DELETE的Method,所以這里只能使用WebRequestCreator來創建
                    HttpWebRequest request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(
                        new Uri(string.Format("http://Bucket.oss.aliyuncs.com/{0}?OSSAccessKeyId={1}&Expires={2}&Signature={3}", fileName, accessKeyId, Convert.ToInt64(DateTimeToUTC(dt.AddMinutes(10))), hash)));

                    request.Method = "PUT";
                    request.ContentType = "multipart/form-data";
                    request.ContentLength = dialog.File.Length;

                    request.Headers = collection;

                    request.BeginGetRequestStream(new AsyncCallback(AsyncRequestStream), request);


                }
                catch (Exception err)
                {
                    new Thread(() =>
                    {
                        System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                        {
                            label1.Content += err.Message;
                        });
                    }).Start();
                }
            }
        }

        /// <summary>
        /// 轉換當前日期至UTC時間格式
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static double DateTimeToUTC(DateTime dt)
        {
            DateTime UnixTimestampLocalZero = System.TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), TimeZoneInfo.Local);
            return (long)(dt - UnixTimestampLocalZero).TotalMilliseconds;
        }

        private void AsyncRequestStream(IAsyncResult ar)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;

                using (Stream stream = request.EndGetRequestStream(ar))
                {
                    stream.Write(buffer, 0, buffer.Length);
                    stream.Flush();
                }

                request.BeginGetResponse(new AsyncCallback(AsyncGetResponse), request);
            }
            catch (Exception err)
            {
                new Thread(() =>
                {
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        label1.Content += err.Message;
                    });
                }).Start();
            }
        }

        private void AsyncGetResponse(IAsyncResult ar)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;

                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);

                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                {
                    string content = sr.ReadToEnd();
                    new Thread(() =>
                    {
                        System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                        {
                            textBlock1.Text += content;
                        });
                    }).Start();
                }

                response.Close();
            }
            catch (WebException err)
            {
                new Thread(() =>
                {
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        label1.Content = err.Status;

                        using (StreamReader sr = new StreamReader(err.Response.GetResponseStream()))
                        {
                            textBlock1.Text += sr.ReadToEnd();
                        }
                    });
                }).Start();
            }
            catch (Exception err)
            {
                new Thread(() =>
                {
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        label1.Content += err.Message;
                    });
                }).Start();
            }
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM