之前玩了下百度bcs,觉得还不错,看了下云存储貌似没.net sdk 但是既然有api就好办嘛,自己动手写个文件上传试试
它的参数用了hmac签名,.net有自带的库,下面是签名方法,这个找了很久...参考着修改了下.还有个疑问,不知道百度是怎么验证签名内容的,因为我们只传入了sign,而hmac据说是不能解密的,只能用密钥来验证
///
/// 对数据进行Hmac签名
///
/// 要签名的数据
/// 密钥
///
private string Hamc(string valueStr, string keyStr)
{
HMAC hmac = HMACSHA1.Create();
//源数据
var data = System.Text.Encoding.UTF8.GetBytes(valueStr);
//密钥
var key = System.Text.Encoding.UTF8.GetBytes(keyStr);
//设置密钥
hmac.Key = key;
//计算哈希值
var hash = hmac.ComputeHash(data);
//对数据进行签名
var signedData = hash.Concat(data).ToArray();
var receivedHash = signedData.Take(hmac.HashSize >> 3).ToArray();
String str = HttpUtility.UrlEncode(Convert.ToBase64String(receivedHash));
return str;
}
然后就是上传文件到服务器了,可以看着进行修改下,下面的方法检索了流的sha1,如果服务器存在则直接返回地址.这里流的读取有一个注意的地方,不能一次读取流的全部,因为某些流不支持查找操作,所以先设了个40kb的缓存
///
/// 上传文件到百度空间,并写入文件数据库
///
/// 输入流 该流必须能够读取
/// 上传的文件名
///
///
public string UploadToBaidu(Stream input, string fileName, string bucket = "kecq-com")
{
if (String.IsNullOrEmpty(fileName))
{
throw new Exception("savePath参数不能为空");
}
fileName = fileName.TrimStart('/');
string savePath = "/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/" + Guid.NewGuid().ToString("N") + Path.GetExtension(fileName);
string fileUrl = "http://bcs.duapp.com/" + bucket + savePath;
string Content = "MBO" + "\n"
+ "Method=PUT" + "\n"
+ "Bucket=kecq-com" + "\n"
+ "Object=" + savePath + "\n";
string sign = Hamc(Content, "xxxxxxxxxxxxx");
string url = "http://bcs.duapp.com/" + bucket + savePath + "?sign=MBO:D200252c02041aac02015b01656582bf:" + sign;
HttpWebResponse res = null;
string returnString = "";
try
{
List data = new List();
byte[] buffer = new byte[40960];
int read = input.Read(buffer, 0, buffer.Length);
while (read > 0)
{
for (int i = 0; i < read; i++)
{
data.Add(buffer[i]);
}
read = input.Read(buffer, 0, buffer.Length);
}
input.Close();
//获取流的sha1码
System.Security.Cryptography.HashAlgorithm algorithm = System.Security.Cryptography.SHA1.Create();
String sha1 = BitConverter.ToString(algorithm.ComputeHash(data.ToArray())).Replace("-", "");
string writeDbUrl = "http://my.fyj.me/service/upload.action?method=POST&userID=xxxxxxxxx&flag=MU&ak=afbf3d192908477d9e24b3e351bc4ebe&sign=0PjZ80oM9HRgyJYGQtmawv2eiwI%3d";
writeDbUrl += "&action=saveFileDb&fileSha1=" + sha1 + "&fileName=" + fileName + "&fileSize=" + data.Count + "&fileUrl=" + HttpUtility.UrlEncode(fileUrl);
string result = FYJ.Common.HttpHelper.DoGet(writeDbUrl);
FYJ.Common.JsonHelper json = new FYJ.Common.JsonHelper(result);
if (json.GetValue("code") != "1")
{
throw new Exception(json.GetValue("message"));
}
else
{
returnString = result;
}
if (json.GetValue("isFileExist") == "0")
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "PUT";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = data.Count;
Stream newStream = req.GetRequestStream();
newStream.Write(data.ToArray(), 0, data.Count);
newStream.Close();
req.GetRequestStream();
res = (HttpWebResponse)req.GetResponse();
Stream ReceiveStream = res.GetResponseStream();
Encoding encode = System.Text.Encoding.UTF8;
StreamReader sr = new StreamReader(ReceiveStream, encode);
// strResult = sr.ReadToEnd();
sr.Close();
ReceiveStream.Close();
}
return returnString;
}
catch (Exception e)
{
return "{\"code\":\"-1\",\"msg\":\""+e.Message+"\"}";
}
finally
{
if (res != null)
{
res.Close();
}
}
}