苦苦搞了半个通宵才搞定的直接使用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();
}
}
}
///
/// 转换当前日期至UTC时间格式
///
///
///
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();
}
}
}
}