R
Raghunathan S
Guest
Hi
I am trying to upload a file in to an Azure Storage Container using REST API, without using any SDKs.
Reason for not using the Azure.Storage.Blobs SDK is, it has a dependency on .netstandard2.0 and some of the DLLs referred by the SDK is not compatible when the project runs .NET Framework 4.6.1. I tried assembly binding redirect in the config and didn't workout well.
Hence i am trying to re-write my Upload code using C# and REST API without the SDK.
Here is code that i am trying
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 = fileInfpenRead())
{
fileContents = new byte[fs.Length];
fs.Read(fileContents, 0, fileContents.Length);
fs.Close();
}
requestStream.Write(fileContents, 0, 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;
}
}
Code to invoke the Upload Method
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);
While executing this line of code
if (request.GetResponse() is HttpWebResponse response)
Exception The remote server returned an error: (403) Forbidden. is thrown
Ran the inputs through PostMan and got these error details.
Error Message:
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'
Any help would be greatly appreciated.
Thanks
Raghunathan S
Continue reading...
I am trying to upload a file in to an Azure Storage Container using REST API, without using any SDKs.
Reason for not using the Azure.Storage.Blobs SDK is, it has a dependency on .netstandard2.0 and some of the DLLs referred by the SDK is not compatible when the project runs .NET Framework 4.6.1. I tried assembly binding redirect in the config and didn't workout well.
Hence i am trying to re-write my Upload code using C# and REST API without the SDK.
Here is code that i am trying
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 = fileInfpenRead())
{
fileContents = new byte[fs.Length];
fs.Read(fileContents, 0, fileContents.Length);
fs.Close();
}
requestStream.Write(fileContents, 0, 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;
}
}
Code to invoke the Upload Method
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);
While executing this line of code
if (request.GetResponse() is HttpWebResponse response)
Exception The remote server returned an error: (403) Forbidden. is thrown
Ran the inputs through PostMan and got these error details.
Error Message:
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'
Any help would be greatly appreciated.
Thanks
Raghunathan S
Continue reading...