I want to generate SAS Token, as per the Azure Doc following is the example for BLOB. I am still getting error. Can you please identify what is the mistake I am doing.
StringToSign = signedpermissions + "\n" +
signedstart + "\n" +
signedexpiry + "\n" +
canonicalizedresource + "\n" +
signedidentifier + "\n" +
signedIP + "\n" +
signedProtocol + "\n" +
signedversion + "\n" +
rscc + "\n" +
rscd + "\n" +
rsce + "\n" +
rscl + "\n" +
rsct
URL = https://myaccount.blob.core.windows.net/mycontainer/test.txt
canonicalizedresource = "/blob/myaccount/mycontainer/test.txt
I am getting following error
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:4b1d1c59-c01e-0052-0197-ffe09f000000
Time:2020-03-21T15:44:34.2757923Z</Message>
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>
Following is my code
public void getSasToken() {
this.storageName = 'zaindevtesting';
this.storageContainer = 'zaindevblob';
this.storageKey = 'xxxxxxZFQ==';
this.storageUrl ='https://zaindevtesting.blob.core.windows.net';
Datetime sasExpiry = Datetime.now();
sasExpiry.addMinutes(15);
Datetime sasStart = Datetime.now();
sasStart.addMinutes(-5);
string signedpermissions = 'rwdlac';
String signedstart = sasStart.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedexpiry = sasExpiry.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedservice = 'b';
String canonicalizedresource = '/blob/zaindevtesting/zaindevblob/test.txt';
string signedidentifier = '';
string signedIP = '';
string signedProtocol = 'https';
string signedversion = '2015-04-05';
string rscc='';
string rscd='';
string rsce='';
string rscl='';
string rsct='';
string stringToSign =signedpermissions + '\n' +
signedstart + '\n' +
signedexpiry + '\n' +
canonicalizedresource + '\n' +
signedidentifier + '\n' +
signedIP + '\n' +
signedProtocol + '\n' +
signedversion + '\n' +
rscc + '\n' +
rscd + '\n' +
rsce + '\n' +
rscl + '\n' +
rsct;
string signedExpiryEncode = EncodingUtil.urlEncode(signedexpiry, 'UTF-8');
string signedStartEncode = EncodingUtil.urlEncode(signedstart, 'UTF-8');
String sasToken = '';
Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
Blob data = Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), unicodeKey);
sasToken = EncodingUtil.base64Encode(data);
String sasTokenString= '?sv=' + signedversion + '&se=' + signedexpiry +'&st='+signedstart+'&sr='+signedservice+'&sp=' + signedpermissions + '&sig=' + sasToken;
string sasURL = 'https://zaindevtesting.blob.core.windows.net/test.txt'+sasTokenString;
System.debug('sasURL--->'+sasURL);
System.debug(sasTokenString);
// return sasToken;
}
This code generate following SAS Link
https://zaindevtesting.blob.core.windows.net/test.txt??sv=2017-11-09&st=2020-03-21T15%3A44%3A07Z&se=2020-03-21T15%3A44%3A07Z&sr=b&sp=rwdc&sig=eJVbGWI4rcyjggOYAE308ilXEA/zAsFYbuNi24IZhX4=
Please try the following code:
public void generateSASToken()
{
string storageName = 'zaindevtesting';
string storageContainer = 'zaindevblob';
string storageKey = 'xxxx==';
string storageUrl ='https://zaindevtesting.blob.core.windows.net';
Datetime sasExpiry = Datetime.now();
sasExpiry = sasExpiry.addMinutes(15);
Datetime sasStart = Datetime.now();
sasStart = sasStart.addMinutes(-5);
string signedpermissions = 'r';
String signedstart = sasStart.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedexpiry = sasExpiry.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedservice = 'b';
String canonicalizedresource = '/blob/zaindevtesting/zaindevblob/test.txt';
string signedidentifier = '';
string signedIP = '';
string signedProtocol = '';
string signedversion = '2015-04-05';
string rscc='';
string rscd='';
string rsce='';
string rscl='';
string rsct='';
string stringToSign =signedpermissions + '\n' +
signedstart + '\n' +
signedexpiry + '\n' +
canonicalizedresource + '\n' +
signedidentifier + '\n' +
signedIP + '\n' +
signedProtocol + '\n' +
signedversion + '\n' +
rscc + '\n' +
rscd + '\n' +
rsce + '\n' +
rscl + '\n' +
rsct;
System.debug('stringToSign--->'+stringToSign);
string signedExpiryEncode = EncodingUtil.urlEncode(signedexpiry, 'UTF-8');
string signedStartEncode = EncodingUtil.urlEncode(signedstart, 'UTF-8');
String sasToken = '';
Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
Blob data = Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), unicodeKey);
sasToken = EncodingUtil.base64Encode(data);
sasToken = EncodingUtil.urlEncode(sasToken, 'UTF-8');
String sasTokenString= '?sv=' + signedversion + '&se=' + signedexpiry +'&st='+signedstart+'&sr='+signedservice+'&sp=' + signedpermissions + '&sig=' + sasToken;
string sasURL = 'https://zaindevtesting.blob.core.windows.net/zaindevblob/test.txt'+sasTokenString;
System.debug('sasURL--->'+sasURL);
System.debug(sasTokenString);
// return sasToken;
}
I just tried it with your storage account key and I was able to download the blob.
Found the following issues with your code:
Permissions has to be in specific order. You're using string signedpermissions = 'rwdlac'; which is not the correct order. I just specified the read permission.
Signed Protocol was specified in stringToString but was not included in the SAS URL. I omitted that from both places.
SAS Token was not URL encoded.
You generated SAS Token for zaindevtesting.blob.core.windows.net/zaindevblob/test.txt URL but forgot to include the blob container name in the final URL.
Related
I am trying to create a file in Azure File Service:
https://learn.microsoft.com/en-us/rest/api/storageservices/create-file
I've seen and read multiple threads about this issue, but I can't figure out what might be the problem in my case... Most likely I am missing some small thing in the request which I cannot find.
The error I am getting: The MAC signature found in the HTTP request (...) is not the same as any computed signature.
The signature string I've used:
PUT
\n
\n
\n
\n
text/plain // Content-Type
\n
\n
\n
\n
\n
\n
x-ms-content-length:1000
x-ms-date:Tue, 20 Apr 2021 19:23:30 GMT
x-ms-type:file
x-ms-version:2015-02-21
/account/share/test
Authorization header:
SharedKey account:XXXXXXXXXX
I've used the HMACSHA256 for hashing the authorization header and signature string, it all works when I use other endpoint (List Shares: https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares), but I can't make it work for the file. I've seen this topic AZURE File Service - Upload PDF through REST API and I believe I am using very similar request, but with no success...
I appreciate any help : )
Edit:
I am not sure if I correctly set the content headers. For example, does the x-ms-content-length should be placed in the CanonicalizedHeaders string?
Edit2:
With regard to what Ivan Yang wrote, I made the code to work, but only when my CanonicalizedHeaders are built like that:
CanonicalizedHeaders := 'x-ms-content-length:1200'
+ LF + 'x-ms-date:' + UTCDateTimeText
+ LF + 'x-ms-file-attributes:Archive' + LF + 'x-ms-file-creation-time:Now' + LF + 'x-ms-file-last-write-time:Now' + LF + 'x-ms-file-permission:Inherit'
+ LF + 'x-ms-type:file' + LF + 'x-ms-version:2019-02-02';
If I have them in different order, then it crashes:
CanonicalizedHeaders := 'x-ms-date:' + UTCDateTimeText + LF +
'x-ms-content-length:1200' + LF +
'x-ms-version:2019-02-02' + LF +
'x-ms-file-attributes:Archive' + LF +
'x-ms-file-creation-time:Now' + LF +
'x-ms-file-last-write-time:Now' + LF +
'x-ms-file-permission:Inherit' + LF +
'x-ms-type:file';
How come does this make a difference?
Your signature string is incorrect(you're missing some "\n"). I'm using the x-ms-version:2019-02-02 instead of the older one x-ms-version:2015-02-21, and the correct signature string should look like this one:
"PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
Here is the c# code using create file api:
using System;
using System.Globalization;
using System.Net;
using System.Security.Cryptography;
namespace ConsoleApp25
{
class Program
{
static void Main(string[] args)
{
string Account = "storage_account_name";
string Key = "storage_account_key";
string FileShare = "file_share_name";
string FileName = "test555.txt";
string apiversion = "2019-02-02";
int content_length = 1200;
string content_type = "text/plain";
DateTime dt = DateTime.UtcNow;
string StringToSign = String.Format("PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
string auth = SignThis(StringToSign, Key, Account);
string method = "PUT";
string urlPath = string.Format("https://{0}.file.core.windows.net/{1}/{2}", Account, FileShare, FileName);
Uri uri = new Uri(urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
request.ContentLength = 0;
request.Headers.Add("x-ms-content-length", $"{content_length}");
request.Headers.Add("Content-Type", content_type);
request.Headers.Add("x-ms-type", "file");
request.Headers.Add("x-ms-date", dt.ToString("R"));
request.Headers.Add("x-ms-version", apiversion);
request.Headers.Add("x-ms-file-attributes", "Archive"); //note it is case-sensitive.
request.Headers.Add("x-ms-file-permission", "Inherit");
request.Headers.Add("x-ms-file-creation-time", "Now");
request.Headers.Add("x-ms-file-last-write-time", "Now");
request.Headers.Add("Authorization", auth);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
//read the response code
Console.WriteLine("the response is:" + response.StatusCode);
}
Console.WriteLine("**completed**");
Console.ReadLine();
}
private static String SignThis(String StringToSign, string Key, string Account)
{
String signature = string.Empty;
byte[] unicodeKey = Convert.FromBase64String(Key);
using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
Account,
signature);
return authorizationHeader;
}
}
}
I am trying to create an Azure SAS to a blob. However, I am getting authentication failed error. Whatever I try, I am not able to construct a well formed stringToSign or signiture.
The error says:
"Signature did not match. String to sign used was rl 2021-03-11T08:08:46Z 2021-03-12T08:08:46Z /blob/{myAccountName}/quickstartcontainer/sampleFile2813061026464365578.txt 2020-02-10 b "
My stringToSign is :
String stringToSign= "rl\n"+
"2021-03-11T08:08:46Z" +"\n" +
"2021-03-12T08:08:46Z"+ "\n"+
"\n"+
"\n"+
"\n"+
"\n"+
2020-02-10"+
"\n"+"\n"+"\n"+"\n"+"\n";
String signature = getHMAC256(key, stringToSign);
My SAS token uri is :
String sasToken = "?sp=rl"
+ "&st=" + "2021-03-11T08:08:46Z"
+ "&se=" + "2021-03-12T08:08:46Z"
+ "&sv=" + "2020-02-10"
+ "&sr=b"
+ "&sig=" + URLEncoder.encode(signature, "UTF-8");
The encryption function is:
public static String computeHMac256(final String base64Key, final String stringToSign) {
try {
byte[] key = Base64.getDecoder().decode(base64Key);
Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
hmacSHA256.init(new SecretKeySpec(key, "HmacSHA256"));
byte[] utf8Bytes = stringToSign.getBytes(StandardCharsets.UTF_8);
return Base64.getEncoder().encodeToString(hmacSHA256.doFinal(utf8Bytes));
} catch (NoSuchAlgorithmException | InvalidKeyException ex) {
throw new RuntimeException(ex);
}
}
How can I generate a well formed signiture for my sas uri?
According to the instructions provided here, your stringToSign should conform to the following structure:
StringToSign = signedPermissions + "\n" +
signedStart + "\n" +
signedExpiry + "\n" +
canonicalizedResource + "\n" +
signedIdentifier + "\n" +
signedIP + "\n" +
signedProtocol + "\n" +
signedVersion + "\n" +
signedResource + "\n"
signedSnapshotTime + "\n" +
rscc + "\n" +
rscd + "\n" +
rsce + "\n" +
rscl + "\n" +
rsct
Which is not the same as what you're doing. Essentially you're missing canonicalizedResource and signedResource parameters.
Please form your stringToSign properly and you should not get the error you're encountering. I think it should be something like (not tested though):
String stringToSign= "rl\n"+
"2021-03-11T08:08:46Z" +"\n" +
"2021-03-12T08:08:46Z"+ "\n"+
"/blob/{myAccountName}/quickstartcontainer/sampleFile2813061026464365578.txt 2020-02-10\n"+
"\n"+
"\n"+
"\n"+
2020-02-10"+"\n"+
"b\n"+"\n"+"\n"+"\n"+"\n"+"\n";
I'm trying to upload a binary file (PDF or Word) to Azure using the Services from C#. I'm restricted to using the REST API's and therefore I cannot use the SDK.
I've managed to create the file but which REST API should I use to upload the content. As far as I can see the PUT RANGE is only for text (not for binary content).
Which File Services REST API should i use? Or is the File Services API not meant for this and should i use the Blob API?
Best regards,
Michel
string endpoint_putrange = "https://" + ssStorageAccount + ".file.core.windows.net/" + ssShareNaam + "/" + ssBestandsNaam + "?comp=range";
Uri _endpoint_putrange = new Uri(endpoint_putrange);
HttpRequestMessage _requestMessage = new HttpRequestMessage(HttpMethod.Put, _endpoint_putrange);
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(20000 * 10000); // 20sec in ticks
httpClient.BaseAddress = _endpoint_putrange;
string RequestDateString = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
// First set the header and construct the canonicalHeader string. See
// These must be in alpabetical order !!!!
string canonicalHeaders = string.Empty;
canonicalHeaders += setHeader(httpClient, "Content-Length", ssBestandsBinary.Length.ToString());
canonicalHeaders += setHeader(httpClient, "x-ms-date", RequestDateString);
canonicalHeaders += setHeader(httpClient, "x-ms-range", "bytes=0-"); // https://learn.microsoft.com/en-us/rest/api/storageservices/specifying-the-range-header-for-file-service-operations
canonicalHeaders += setHeader(httpClient, "x-ms-version", "2020-04-08"); // https://learn.microsoft.com/nl-nl/rest/api/storageservices/versioning-for-the-azure-storage-services
canonicalHeaders += setHeader(httpClient, "x-ms-write", "Update");
// Construct the canonicalResource string
string canonicalResource = "/" + ssStorageAccount + "/" + ssShareNaam + "/" + ssBestandsNaam;
// Construct the string to Sign
string stingToSign = "PUT\n" + /*HTTP Verb*/
"\n" + /*Content-Encoding*/
"\n" + /*Content-Language*/
ssBestandsBinary.Length.ToString() + "\n" + /*Content-Length (empty string when zero)*/
"\n" + /*Content-MD5*/
"\n" + /*Content-Type*/
"\n" + /*Date*/
"\n" + /*If-Modified-Since */
"\n" + /*If-Match*/
"\n" + /*If-None-Match*/
"\n" + /*If-Unmodified-Since*/
"bytes=0-" + "\n" + /*Range*/
canonicalHeaders + /*CanonicalizedHeaders*/
canonicalResource; /*CanonicalizedResource*/
// Sign it
HMACSHA256 hmac = new HMACSHA256();
byte[] dataToHmac = Encoding.UTF8.GetBytes(stingToSign);
string signature = Convert.ToBase64String(hmac.ComputeHash(dataToHmac));
// Add the authorization header
string authorizationHeader = ssStorageAccount + ":" + signature;
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("SharedKey", authorizationHeader);
// How to specify the binary content of the _requestmessage/httpClient
/// ?????????????????????????
// Do the (synchronous) call and collect the response
HttpResponseMessage httpResponse = httpClient.SendAsync(_requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None).GetAwaiter().GetResult();
..... etc etc
Please try by setting the Content property of your _requestMessage. I am assuming that variable ssBestandsBinary is a byte array so you can set the Content property as ByteArrayContent.
Your code could be something like (not tested though):
_requestMessage.Content = new ByteArrayContent(ssBestandsBinary);
HttpResponseMessage httpResponse = httpClient.SendAsync(_requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None).GetAwaiter().GetResult();
I am trying to generate Account SAS token:
MSDN DOC
When I am trying to use generated token, I get following:
AuthenticationFailed
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:89959111-0001-00c8-24d1-e0515b000000
Time:2016-07-18T08:49:00.8383767Z
Signature did not match. String to sign used was [accountName]
rl
b
sc
2017-01-01
2015-04-05
Here are my code:
var signedVersion = "2015-04-05";
var signedServices = "b";
var signedResourceTypes = "sc";
var signedPermission = "rl";
var signedExpiry = "2017-01-01";
var stringToSign =
accountName + "\n" +
signedPermission + "\n" +
signedServices + "\n" +
signedResourceTypes + "\n" +
signedExpiry + "\n" +
signedVersion + "\n"
;
var keyBytes = Encoding.UTF8.GetBytes(accountKey);
byte[] hash;
using (var mac = new HMACSHA256(keyBytes))
{
var stringToSignBytes = Encoding.UTF8.GetBytes(stringToSign);
hash = mac.ComputeHash(stringToSignBytes);
}
var str = Convert.ToBase64String(hash);
var sig = HttpUtility.UrlEncode(str);
var url = $"https://{accountName}.blob.core.windows.net/?comp=list&sv={signedVersion}&ss={signedServices}&srt={signedResourceTypes}&sp={signedPermission}&se={signedExpiry}&sig={sig}";
What am I doing wrong?
I noticed a few issues with the code:
First, to convert account key into byte array you would need to use Convert.FromBase64String(accountKey) instead of Encoding.UTF8.GetBytes(accountKey);.
Next, even if you're not using start time, signed protocol and signed IP addresses, you would need to include them in your stringToSign.
Once you do these things, the code should work. Based on these, I have included the modified code below. I tested it for listing containers in my storage account and it works.
static void AccountSas()
{
var signedVersion = "2015-04-05";
var signedServices = "b";
var signedResourceTypes = "sc";
var signedPermission = "rl";
var signedExpiry = "2017-01-01";
var signedStart = "";
var signedIP = "";
var signedProtocol = "";
var stringToSign =
accountName + "\n" +
signedPermission + "\n" +
signedServices + "\n" +
signedResourceTypes + "\n" +
signedStart + "\n" +
signedExpiry + "\n" +
signedIP + "\n" +
signedProtocol + "\n" +
signedVersion + "\n"
;
var keyBytes = Convert.FromBase64String(accountKey);
byte[] hash;
using (var mac = new HMACSHA256(keyBytes))
{
var stringToSignBytes = Encoding.UTF8.GetBytes(stringToSign);
hash = mac.ComputeHash(stringToSignBytes);
}
var str = Convert.ToBase64String(hash);
var sig = HttpUtility.UrlEncode(str);
var url = string.Format("https://{0}.blob.core.windows.net/?comp=list&sv={1}&ss={2}&srt={3}&sp={4}&se={5}&sig={6}", accountName, signedVersion, signedServices, signedResourceTypes, signedPermission, signedExpiry, sig);
}
Hi All i'm having an application which pulls YouTube analytics data but it is not working from sometime. The details are below with code
for (int ISOCountryCode = 0; ISOCountryCode < ds.Tables[0].Rows.Count; ISOCountryCode++)
{
//validation to check if date is null
string strdimensions = "day";
string strmetrics = "views,comments,favoritesAdded,favoritesRemoved,likes,dislikes,shares,estimatedMinutesWatched,averageViewDuration,averageViewPercentage,annotationClickThroughRate,annotationCloseRate,subscribersGained,subscribersLost,uniques";
string strstartdate = Convert.ToDateTime(WeekStartDate).ToString("yyyy-MM-dd");
string strenddate = Convert.ToDateTime(WeekEndDate).ToString("yyyy-MM-dd");
string DownloadURL = string.Format("https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel==" + ChannelID + "&start-date=" + strstartdate + "&end-date=" + strenddate + "&metrics=" + strmetrics + "&key=KE9gM-4_tgmVw3L3QaMSeR-G4X5vr7tA&access_token=" + token + "&dimensions=" + strdimensions + "&alt=csv&filters=country==" + ds.Tables[0].Rows[ISOCountryCode]["ISOCode"].ToString());
urlDownload.Download(DownloadURL, "Z:\\InsightData\\ChannelData\\UnZipFilesFldr\\" + ChannelID + "_world_" + ds.Tables[0].Rows[ISOCountryCode]["ISOCode"].ToString() + ".csv");
strdimensions = "day,operatingSystem,deviceType";
strmetrics = "estimatedMinutesWatched,views";
DownloadURL = string.Format("https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel=={2}&start-date=" + strstartdate + "&end-date=" + strenddate + "&metrics=" + strmetrics + "&key=KE9gM-4_tgmVw3L3QaMSeR-G4X5vr7tA&access_token={0}&dimensions=" + strdimensions + "&alt=csv&filters=country=={1}", token, ds.Tables[0].Rows[ISOCountryCode]["ISOCode"].ToString(), ChannelID);
urlDownload.Download(DownloadURL, "Z:\\InsightData\\ChannelData\\UnZipFilesFldr\\" + ChannelID + "_world-device_" + ds.Tables[0].Rows[ISOCountryCode]["ISOCode"].ToString() + ".csv");
strdimensions = "day,operatingSystem,deviceType";
strmetrics = "estimatedMinutesWatched,views";
DownloadURL = string.Format("https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel=={2}&start-date=" + strstartdate + "&end-date=" + strenddate + "&metrics=" + strmetrics + "&key=KE9gM-4_tgmVw3L3QaMSeR-G4X5vr7tA&access_token={0}&dimensions=" + strdimensions + "&alt=csv&filters=country=={1}", token, ds.Tables[0].Rows[ISOCountryCode]["ISOCode"].ToString(), ChannelID);
urlDownload.Download(DownloadURL, "Z:\\InsightData\\ChannelData\\UnZipFilesFldr\\" + ChannelID + "_world-deviceType_" + ds.Tables[0].Rows[ISOCountryCode]["ISOCode"].ToString() + ".csv");
}
The Code in the urlDownload.Download is :-
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(strURLFileandPath);
HttpWebResponse ws = (HttpWebResponse)wr.GetResponse();
Stream str = ws.GetResponseStream(); - > Line Of Error
On the last line where it asks for the response stream it errors out and says "500 Internal Server Error"