苦苦搞了半个通宵才搞定的直接使用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(); } } } }