如何解决使用REST API和C#将PDF文件上传到Azure Blob存储不使用任何AZURE STORAGE SDK
我正在尝试使用REST API将文件上传到Azure存储容器中,而不使用任何SDK。
不使用Azure.Storage.Blobs SDK的原因是,它依赖于.netstandard2.0,并且在项目运行.NET Framework 4.6.1时,SDK引用的某些DLL不兼容。我在配置中尝试了程序集绑定重定向,但没有很好地进行锻炼(System.ValueTuple.dll参考问题)。
因此,我试图使用C#和REST API在没有SDK的情况下重新编写我的上载代码。
这是我正在尝试的代码
public class AzureRestApi
{
private string _x_ms_client_request_id = string.Empty;
private string _x_ms_date = string.Empty;
public string AzureStorageAccountName { get; set; }
public string AzureStorageAccessKey { get; set; }
public string BlobSaveFolder
{
get; set;
}
public string X_MS_DATE
{
get
{
return _x_ms_date;
}
}
public string X_MS_VERSION
{
get
{
return "2019-12-12";
}
}
public string BaseURI
{
get
{
return string.Format("https://{0}.blob.core.windows.net/",AzureStorageAccountName);
}
}
public AzureRestApi()
{
//Date and GUID should be same that is used to create the key signing string and the one that is being sent in the
//header of REST api requests.
_x_ms_date = DateTime.UtcNow.ToString("R",CultureInfo.InvariantCulture);
_x_ms_client_request_id = System.Guid.NewGuid().ToString();
}
public bool UploadBlobToContainer(string filePath,string containerName)
{
bool isUploaded = false;
try
{
FileInfo fileInfo = new FileInfo(filePath);
long contentLength = fileInfo.Length;
long range = contentLength - 1;
string method = "PUT";
string contentType = "application/pdf";
string blobName = fileInfo.Name;
string blobURI = BaseURI + containerName + "/" + blobName;
string xmsHeader = $"x-ms-blob-type:BlockBlob\nx-ms-date:{X_MS_DATE};\nx-ms-version:{X_MS_VERSION}";
string resHeader = $"/{AzureStorageAccountName}/{containerName}/{blobName}";
if (WebRequest.Create(blobURI) is HttpWebRequest request)
{
request.Method = method;
request.ContentType = contentType;
request.ContentLength = contentLength;
request.Headers.Add("x-ms-blob-type","BlockBlob");
request.Headers.Add("x-ms-date",X_MS_DATE);
request.Headers.Add("x-ms-version",X_MS_VERSION);
request.Headers.Add("Authorization",GetAuthorizationHeader(method,xmsHeader,resHeader,request));
using (Stream requestStream = request.GetRequestStream())
{
byte[] fileContents = null;
using (FileStream fs = fileInfo.OpenRead())
{
fileContents = new byte[fs.Length];
fs.Read(fileContents,fileContents.Length);
fs.Close();
}
requestStream.Write(fileContents,fileContents.Length);
}
if (request.GetResponse() is HttpWebResponse response)
{
if (response.StatusCode == HttpStatusCode.OK)
isUploaded = true;
else
isUploaded = false;
}
}
}
catch (Exception ex)
{
Log.LogException(ex);
}
return isUploaded;
}
private string GetAuthorizationHeader(string method,string xmsHeader,string resHeader,HttpWebRequest request)
{
string strToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{xmsHeader}\n{resHeader}";
string signatureString = GetHashedString(strToSign,AzureStorageAccessKey);
string authorizationHeader = string.Format(
CultureInfo.InvariantCulture,"{0} {1}:{2}","SharedKey",AzureStorageAccountName,signatureString);
return authorizationHeader;
}
}
调用Upload函数的代码
string storageName = "MyDefaultStorage";
string containerName = "MyDefaultContainer";
AzureRestApi restApi = new AzureRestApi()
{
AzureStorageAccountName = storageName,AzureStorageAccessKey = "MY_STORAGE_ACCOUNT_ACCESS_KEY",};
restApi.UploadBlobToContainer("E:\\UploadFiles\\UploadDocument1.pdf",containerName);
执行此行时抛出异常
if (request.GetResponse() is HttpWebResponse response)
异常消息:远程服务器返回错误:(403)禁止。
我尝试使用PostMan模拟此请求,并收到此错误消息
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
The MAC signature found in the HTTP request 'RW1ACnL1aYqtSnJeHhV2694Ek95Olnf+V3Eup4Jt5ng=' is not the same as any computed signature. Server used following string to sign: 'PUT
461804
application/pdf
x-ms-blob-type:BlockBlob
x-ms-date:Wed,12 Aug 2020 19:30:20 GMT
x-ms-version:2019-12-12
/MyDefaultStorage/MyDefaultContainer/UploadDocument1.pdf'
我尝试了这些链接中给出的答案,如果该文件是文本文件,则可以使用,但是尝试使用pdf时失败
Azure rest api put blob REST Api to Azure blob storage using Access key
任何帮助将不胜感激。
谢谢 拉古纳森S
解决方法
您在此代码中添加了一个额外的分号:
string xmsHeader = $"x-ms-blob-type:BlockBlob\nx-ms-date:{X_MS_DATE};\nx-ms-version:{X_MS_VERSION}";
请更改为此:
string xmsHeader = $"x-ms-blob-type:BlockBlob\nx-ms-date:{X_MS_DATE}\nx-ms-version:{X_MS_VERSION}";
希望这可以为您提供帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。