Download folder from Amazon S3 bucket using .net SDK - c#

How to download entire folder present inside s3 bucket using .net sdk.Tried with below code, it throws invalid key.I need to download all files present inside nested pesudo folder present inside bucket and removing file download limitations to 1000 which is default.
public static void DownloadFile()
{
var client = new AmazonS3Client(keyId, keySecret, bucketRegion);
ListObjectsV2Request request = new ListObjectsV2Request
{
BucketName = bucketName + "/private/TargetFolder",
MaxKeys = 1000
};
try
{
ListObjectsV2Response bucketResponse = client.ListObjectsV2(request);
foreach (S3Object o in bucketResponse.S3Objects)
{
var getRequest = new GetObjectRequest
{
BucketName = bucketResponse.Name + "/private/TargetFolder",
Key = bucketResponse.Name +"/private/TargetFolder/"+ o.Key
};
var response = client.GetObject(getRequest);
response.WriteResponseStreamToFile(downloadLocation + "\\" + o.Key);
var responseCode = response.HttpStatusCode;
if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
{
Console.WriteLine($"Success downloaded : {o.Key}");
}
else if (response.HttpStatusCode == System.Net.HttpStatusCode.RequestTimeout)
{
Console.WriteLine("Request Timeout error.");
}
else if (response.HttpStatusCode == System.Net.HttpStatusCode.ServiceUnavailable)
{
Console.WriteLine("Service Unavailable.");
}
else if (response.HttpStatusCode == System.Net.HttpStatusCode.InternalServerError)
{
Console.WriteLine("Internal Server error.");
}
else
{
Console.WriteLine("Please check the provided AWS Credentials.");
}
}
}
catch (AmazonS3Exception amazonS3Exception)
{
if (amazonS3Exception.ErrorCode != null &&
(amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
{
Console.WriteLine("Please check the provided AWS Credentials.");
}
else
{
Console.WriteLine(amazonS3Exception.Message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
Thanks in advance!

If you are always getting 0 in S3Objects.Count, try without using Delimiter property:
public async Task DownloadDirectoryAsync()
{
var bucketRegion = RegionEndpoint.USEast2;
var credentials = new BasicAWSCredentials(accessKey, secretKey);
var client = new AmazonS3Client(credentials, bucketRegion);
var bucketName = "bucketName";
var request = new ListObjectsV2Request
{
BucketName = bucketName,
Prefix = "directorey/",
MaxKeys = 1000
};
var response = await client.ListObjectsV2Async(request);
var utility = new TransferUtility(s3Client);
var downloadPath = "c:\\your_folder";
foreach (var obj in response.S3Objects)
{
utility.Download($"{downloadPath}\\{obj.Key}", bucketName, obj.Key);
}
}
And of course, you need s3:ListBucket permission

Try this, it works for me
public static void DownloadFile()
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls | SecurityProtocolType.Tls;
var client = new AmazonS3Client(keyId, keySecret, bucketRegion);
ListObjectsRequest request = new ListObjectsRequest();
request.BucketName = "BUCKET_NAME";
request.Prefix = "private/TargetFolder";
request.Delimiter = "/";
request.MaxKeys = 1000;
ListObjectsResponse response = client.ListObjects(request);
var x = response.S3Objects;
foreach (var objt in x)
{
GetObjectRequest request1 = new GetObjectRequest();
request1.BucketName = "BUCKET_NAME";
request1.Key = objt.Key;
GetObjectResponse Response = client.GetObject(request1);
if(objt.Size > 0){
using (Stream responseStream = Response.ResponseStream)
{
Response.WriteResponseStreamToFile(downloadLocation + "\\" + objt.Key);
}
}
}
}

The solution marked as accepted uses client.ListObjects(request) which says on the descrition that will only take a max of 1000 files, if there are more files on the folder maybe the code below will work. Thanks.
public void DownloadallBucketFiles(string bucketName, string folderPath =
null)
{
var bucketRegion = RegionEndpoint.USEast1;
var credentials = new BasicAWSCredentials(S3CredentialsKey,
S3CredentialsSecret);
var s3Client = new AmazonS3Client(credentials, bucketRegion);
var utility = new TransferUtility(s3Client);
var dir = new S3DirectoryInfo(s3Client, bucketName);
var filesInBucket = dir.EnumerateFiles()?.ToList();
var path = (string.IsNullOrEmpty(folderPath)) ? S3LocalTempDir :
folderPath;
if (filesInBucket == null)
return;
filesInBucket.ForEach(file =>
{
try
{
if (!File.Exists(Path.Combine(path, file.Name)))
utility.Download($"{path}\\{file.Name}", bucketName,
file.Name);
Console.WriteLine(file.Name + " Processed");
}
catch(Exception ex)
{
Console.WriteLine(file.Name + $" download failed with error:
{ex.Message}");
}
});
}
}

Related

File Upload to S3 is occasionally 0 KB

We are using S3 to store excel files. I first parse through the file to grab some data to save to the database before I upload it to the S3 bucket. Though I have yet to get this to happen on my local machine, when this is deployed, the tester sometimes sees the uploaded file being 0 KB even though it was parsed and data was saved to the database.It doesn't happen on my machine and only happens when deployed intermittently. Any ideas of how to resolve this?
[HttpPost("ingesttestmatrix")]
[ProducesResponseType(typeof(TestMatrixResponse), StatusCodes.Status200OK)]
public ActionResult<string> IngestTestMatrix([FromForm] Guid authenticateduserid, [FromForm] Guid testeventid, IFormFile filename)
{
TestMatrixResponse rsp = new TestMatrixResponse();
List<string> BadDataColumns = new List<string>();
Guid TestMatrixID = Guid.NewGuid();
//string newDictName = System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + #"\TempFiles" + Guid.NewGuid();
string newDictName = AppContext.BaseDirectory + #"\TempLLDBFiles" + Guid.NewGuid();
System.IO.Directory.CreateDirectory(newDictName);
string baseFileName = Request.Form.Files[0].FileName;
string newFileName = newDictName + #"\" + baseFileName;
try
{
//create file from stream and then open it for ingesting
var file = Request.Form.Files[0];
if (file.Length > 0)
{
using (FileStream fileStream = new FileStream(newFileName, FileMode.Create))
{
file.CopyTo(fileStream);
fileStream.Close();
}
}
//Do some cool db stuff
Model.Managers.AmazonFileManager.UploadFile(newFileName, testeventid.ToString()).Wait();
}
catch (Exception ex)
{
rsp.message = ex.Message.Replace("\"", "");
LoggingEvent lge = new LoggingEvent(LoggingEventTypeEnum.Error, "Ingest Test Matrix ", ex.Message, authenticateduserid.ToString());
LoggingEventController leController = new LoggingEventController();
leController.InsertLoggingEvent(authenticateduserid, lge, LoggingEventTypeEnum.Error);
rsp.success = false;
}};
public static async Task UploadFile(string filePath, string itemGuid)
{
try
{
var s3Client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1);
var fileTransferUtility = new TransferUtility(s3Client);
string bucketName = "";
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("AWSBucketName")))
bucketName = Environment.GetEnvironmentVariable("AWSBucketName");
else
bucketName = _iConfig.GetSection("AWSBucketName").Value;
PutObjectRequest putObjectRequest = new PutObjectRequest
{
BucketName = bucketName,
StorageClass = S3StorageClass.Standard,
Key = itemGuid + "/",
ContentBody = itemGuid
};
await s3Client.PutObjectAsync(putObjectRequest);
string fileKey = itemGuid + "/" + Path.GetFileName(filePath);
await fileTransferUtility.UploadAsync(filePath, bucketName, fileKey);
}
catch (AmazonS3Exception amazonS3Exception)
{
if (amazonS3Exception.ErrorCode != null &&
(amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId")
||
amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
{
throw new Exception("AWS Error: Check the provided AWS Credentials.");
}
else
{
throw new Exception("AWS Error: " + amazonS3Exception.Message);
}
}
}

Response 400 on the post of httpclient in dotnet core

I am wrote the code to POST from my web application but it is sending 400 bad request.
See the my controller class:
[HttpPost]
public async Task<IActionResult> CreateAgent(AgentCreateDto agentCreateDto)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://localhost:44331/api/");
var responseTask = client.PostAsJsonAsync("Agent/CreateAgent", agentCreateDto);
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var newAgentAdd = JsonConvert.DeserializeObject<AgentCreateDto>(await result.Content.ReadAsStringAsync());
var newAgent = newAgentAdd;
TempData["SuccessMessage"] = $"Agent {newAgent.FirstName} was successfully created.";
return RedirectToAction("AgentLists");
//return RedirectToAction("GetAgentById", new { AgentId = newAgent.usersId});
}
}
return View();
}
Here is below the problem image please see for the reference.
Here is api code for that I am send the request:
[HttpPost("CreateAgent")]
public async Task<IActionResult> CreateAgent([FromForm]AgentCreateDto agentCreateDto)
{
if (!ModelState.IsValid)
{
return BadRequest("Invalid model object");
}
if (agentCreateDto.ProfileImage != null)
{
string uniqueFileName = UploadProfileImage(agentCreateDto.ProfileImage);
agentCreateDto.ProfileNewImage = uniqueFileName;
}
var createAgent = await _userService.CreateAgent(agentCreateDto);
//_logger.LogInformation($"User added to the for file test. ");
return Created("", new
{
Id = createAgent.UsersId,
Message = "Agent created Successfully",
Status = "Success",
UserType = createAgent.UserType
});
}
And for image uploading code at the API side:
private string UploadProfileImage(IFormFile ProfileImage)
{
string uniqueFileName = null;
if (ProfileImage != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.ContentRootPath, "ProfileImage");
uniqueFileName = Guid.NewGuid().ToString() + "_" + ProfileImage.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
ProfileImage.CopyTo(fileStream);
}
}
return uniqueFileName;
}
The correct way to post file and additional data by HttpClient like below:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://localhost:44331/api/");
var formContent = new MultipartFormDataContent();
formContent.Add(new StringContent(agentCreateDto.Id.ToString()), nameof(agentCreateDto.Id));
formContent.Add(new StringContent(agentCreateDto.Message), nameof(agentCreateDto.Message));
formContent.Add(new StringContent(agentCreateDto.UserType), nameof(agentCreateDto.UserType));
//other proerties....
formContent.Add(new StreamContent(agentCreateDto.ProfileImage.OpenReadStream()), nameof(agentCreateDto.ProfileImage), Path.GetFileName(agentCreateDto.ProfileImage.FileName));
//change PostAsJsonAsync to PostAsync.....
var responseTask = client.PostAsync("/Agent/CreateAgent", formContent);
responseTask.Wait();
var result = responseTask.Result;
//more code...
}

Why Sending Apple Push Notifications, and Android using TcpClient cause application to hang?

I have searched the web and I could not find a solution to my problem.
I have a project targeting .net Framework 4.0.
I have two methods. One to push notification to ios devices, the other one to push notification to android devices.
Here is my first method :
public void SendAplePushNotificationMessage(string body, int Participant_ID, int Trainer_ID)
{
var componentSetup = new ComponentSetup();
var odsDevicesToken = componentSetup.getDevicesToken(Participant_ID, Trainer_ID, 1);
if (odsDevicesToken.Tables[0].Rows.Count > 0)
{
foreach (DataRow dr in odsDevicesToken.Tables[0].Rows)
{
try
{
var deviceToken = HexStringToByteArray(dr["DeviceToken"].ToString());
var memoryStream = new MemoryStream();
var writer = new BinaryWriter(memoryStream);
writer.Write((byte)0); //The command
writer.Write((byte)0); //The first byte of the deviceId length (big-endian first byte)
writer.Write((byte)32); //The deviceId length (big-endian second byte)
writer.Write(deviceToken);
writer.Write((byte)0); //First byte of payload length; (big-endian first byte)
var payload = "{\"aps\":{\"alert\":\"" + body + "\",\"badge\":1,\"sound\":\"default\"}}";
var b1 = Encoding.UTF8.GetBytes(payload);
if (b1.Length > 256)
{
body = body.Substring(0, 106) + "...";
payload = "{\"aps\":{\"alert\":\"" + body + "\",\"badge\":1,\"sound\":\"default\"}}";
b1 = Encoding.UTF8.GetBytes(payload);
}
writer.Write((byte)b1.Length);
writer.Write(b1);
writer.Flush();
var array = memoryStream.ToArray();
memoryStream.Write(Encoding.ASCII.GetBytes(body), 0, body.Length);
var port = Convert.ToInt32(ConfigurationManager.AppSettings["APNPortNo"]);
var hostname = ConfigurationManager.AppSettings["APNHostName"];
var certificatePath = Server.MapPath("~") + ConfigurationManager.AppSettings["APNCertificatePath"].Replace("/", "\\");
Logger.LogInfoMessage("certificatePath: " + certificatePath);
var clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "");
var certificatesCollection = new X509Certificate2Collection(clientCertificate);
var client = new TcpClient(hostname, port);
var sslStream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
sslStream.Write(array);
sslStream.Flush();
client.Close();
}
catch (AuthenticationException ex)
{
client.Close();
var setupObj = new ComponentSetup();
setupObj.AddErrorLog(ex.Message, CamelRaceContext.UserSettings.User.USER_NAME, null,
Participant_ID, dr["DeviceToken"].ToString());
if (ex.InnerException != null)
Logger.LogErrorMessage(ex.InnerException, ex.InnerException.Message);
throw new CamelRaceApplicationException<MobileAdmin_ManageNotifications>(ex.Message, ex);
}
catch (CamelRaceApplicationException<MobileAdmin_ManageNotifications> ex)
{
throw new CamelRaceApplicationException<MobileAdmin_ManageNotifications>(ex.Message,ex);
}
catch (Exception e)
{
client.Close();
var setupObj = new ComponentSetup();
setupObj.AddErrorLog(e.Message, CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID, dr["DeviceToken"].ToString());
}
}
catch (CamelRaceApplicationException<MobileAdmin_ManageNotifications> ex)
{
throw new CamelRaceApplicationException<MobileAdmin_ManageNotifications>(ex.Message, ex);
}
catch (Exception exMain)
{
var setupObj = new ComponentSetup();
setupObj.AddErrorLog(exMain.Message, CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID, dr["DeviceToken"].ToString());
if (exMain.InnerException != null)
Logger.LogErrorMessage(exMain.InnerException, exMain.InnerException.Message);
}
}
}
}
The second Method is :
private void SendGCMPushNotificationMessage(string body, int Participant_ID, int Trainer_ID)
{
var _ComponentSetup = new ComponentSetup();
var odsDevicesToken = _ComponentSetup.getDevicesToken(Participant_ID, Trainer_ID , 2);
if (odsDevicesToken.Tables[0].Rows.Count > 0)
{
var registration_ids = new string[odsDevicesToken.Tables[0].Rows.Count];
var index = 0;
foreach (DataRow dr in odsDevicesToken.Tables[0].Rows)
{
registration_ids[index] = dr["DeviceToken"].ToString();
index = index + 1;
}
if (registration_ids.Length > 0)
{
var GcmHttpUrl = ConfigurationManager.AppSettings["GcmHttpUrl"];
var GcmApiKey = ConfigurationManager.AppSettings["GcmApiKey"];
var notificationData = new JObject(
new JProperty("registration_ids", new JArray(registration_ids)),
new JProperty("notification", new JObject(
new JProperty("title", ConfigurationManager.AppSettings["title"]),
new JProperty("body", body),
new JProperty("icon", "myicon"),
new JProperty("sound", "default")
)),
new JProperty("data", new JObject(
new JProperty("state", ConfigurationManager.AppSettings["state"])
)
)
);
var contentText = notificationData.ToString(Formatting.None);
var content = Encoding.UTF8.GetBytes(contentText);
try
{
var req = (HttpWebRequest)WebRequest.Create(GcmHttpUrl);
req.Method = "POST";
// Disable expect-100 to improve latency
req.ServicePoint.Expect100Continue = false;
req.ContentType = "application/json";
req.ContentLength = content.Length;
req.Headers.Add("Authorization", "key=" + GcmApiKey);
using (var s =req.GetRequestStream())
{
s.Write(content, 0, content.Length);
s.Close();
}
// Receive the HTTP response.
string response;
using (var res = (HttpWebResponse) req.GetResponse())
{
// Read the request body
using (TextReader r = new StreamReader(res.GetResponseStream(), Encoding.UTF8, true))
{
response = r.ReadToEnd();
}
}
Console.WriteLine("Response: " + response);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.ToString());
var setupObj = new ComponentSetup();
setupObj.AddErrorLog("Exception: " + ex.ToString(), CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID,null);
if (ex is WebException)
{
var webex = (WebException)ex;
if (webex.Response != null)
{
var status = ((HttpWebResponse)webex.Response).StatusCode;
setupObj.AddErrorLog("Exception: " + status.ToString(), CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID, null);
// Check the status code here...
}
}
}
}
}
}
Now, this code is working fine when number of devices is 3 or 4.
When this number increase. Like 8423.
It causes the application to hang.
Currently I am calling this code on button click.
I was wondering will putting this code using task class will make it work ?
var task1 = Task.Factory.StartNew(() =>SendAplePushNotificationMessage(txtNotification.Text, Participant_ID, Trainer_ID) , TaskCreationOptions.LongRunning);
var task2 = Task.Factory.StartNew(() => SendGCMPushNotificationMessage(txtNotification.Text, Participant_ID, Trainer_ID), TaskCreationOptions.LongRunning);
Task.WaitAll(task1, task2);
I know some of you will propose to use pushsharp.
I was thinking of doing so.
However push sharp targets 4.5.
My project target 4.0.
Upgrade is not an option.
Will my solution work ?
If not, how can I solve my problem then.
Thanks.

Incorporating GZIP into Web API

I have a C# application that communicates to my Web API service fine when there is no GZIP being used. When I apply GZIP, my [FromBody] variable is null and I can't seem to pinpoint why this is happening.
If I put a breakpoint in the web api, I can see that data is null when GZIP is applied. When it's not, it is populated.
Any input would be greatly appreciated. If you need any other code examples please let me know
Update Routing Class
public class UpdateRouting
{
public UpdateRouting()
{
Routes = new List<Routing>();
}
public List<Routing> Routes { get; set; }
}
Collect data
private void btnTestRoutingSend_Click(object sender, EventArgs e)
{
try
{
var response = new ResponseObj();
using (var mainContext = new EntityModel())
{
var nodes = mainContext.Nodes.Where(x => x.SystemType == "Dev").ToList();
var updRouting = new UpdateRouting();
foreach (var n in nodes)
{
using (var nodeContext = new EntityModel(connString))
{
var accounts = nodeContext.Accounts;
foreach (var acct in accounts)
{
//code to map accounts to route
}
var customers = nodeContext.Customers;
foreach (var cust in customers)
{
//code to map customer to route
}
}
}
response = webcontext.SendPost<ResponseObj>(updRouting, "Routing", "SyncRouting");
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
SendPost Method
public T SendPost<T>(object update, string controller, string action)
{
var url = _baseURL + String.Format("api/{0}/{1}", controller, action), update);
T retval = default(T);
var uri = new Uri(_baseUri, url);
try
{
var request = GetRequest(uri, method);
if (content != null)
{
var json = GetBodyString(content);
if (!_useCompression)
{
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
var json = GetBodyString(content);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
} else{
using (var gzipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress, false))
{
using (var streamWriter = new StreamWriter(gzipStream))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
}
httpWebRequest.Headers.Add("Content-Encoding", "gzip");
}
}
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
retval = GetObject<T>(result);
}
}
catch (Exception e)
{
_log.Error(string.Format("Error sending {0} request to {1}", method, uri.ToString()), e);
}
return retval;
}
Get Request
protected virtual HttpWebRequest GetRequest(Uri uri, string method)
{
var retval = (HttpWebRequest)WebRequest.Create(uri);
retval.Timeout = 1000 * 60 * 5;
retval.Accept = "application/json";
retval.KeepAlive = true;
retval.ContentType = "application/json";
retval.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
retval.Method = method;
return retval;
}
API Call
[System.Web.Http.HttpPost]
[Route("SyncRouting")]
public ResponseObj SyncRouting([FromBody] UpdateRouting data)
{
var response = new ResponseObj();
try
{
// do stuff
response.Successful = true;
return response;
}
catch (Exception e)
{
response.Successful = false;
response.Errors.Add(new ErrorMsg
{
Message = "Error - " + e.ToString(),
ExceptionMessage = e.Message,
StackTrace = e.StackTrace,
InnerException = e.InnerException.ToString()
});
return response;
}
}

How to create a virtual application and directories in azure website programmatically

We use Windows Azure website management library and create a web app programmatically by using C# code but we cannot create a virtual directory inside a web app. please help me how to create virtual directory inside a web app programmatically
My Code here
var websiteManagementClient =
CloudContext.Clients.CreateWebSiteManagementClient(Credentials);
var webSpaces = websiteManagementClient.WebSpaces.List();
var webSpace = webSpaces.FirstOrDefault(x => x.GeoRegion == "South Central US");
if (webSpace == null)
{
throw new Exception(string.Format("No webspace for region {0} found", "South Central US"));
}
var webHostingPlans = websiteManagementClient.WebHostingPlans.List(webSpace.Name);
var webHostingPlan = webHostingPlans.FirstOrDefault();
if (webHostingPlan == null)
{
throw new Exception(string.Format("No webhostingplan found"));
}
try
{
var website = websiteManagementClient.WebSites.Get(webSpace.Name, "MyAzureTestSite", null);
if (website != null)
{
throw new Exception(string.Format("The website {0} already exists", ""));
}
}
catch (Exception)
{
}
var websiteCreateParams = new WebSiteCreateParameters();
websiteCreateParams.Name = "MyAzureTestSite";
websiteCreateParams.ServerFarm = webHostingPlan.Name;
websiteManagementClient.WebSites.Create(webSpace.Name, websiteCreateParams);
At first I tried to create virtual directory with the help of Azure SDK but was not successful. Finally, I used http request to create it.
If you can use this method, you can check it out on my blog.
http://kapiltak.blogspot.in/2015/10/how-to-create-virtual-application-in.html
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Threading;
namespace ConsoleApplication1
{
public class Azure
{
private string loginpath = "https://login.windows.net/{0}";
private string apiEndpoint = "https://management.azure.com/";
//Fill these up
private string webSiteName = "{your webSiteName}";
private string webSpaceName = "Default-Web-SoutheastAsia"; //Insert your webSpaceName here
private string tenantId = "{your tenantId}";
private string clientId = "{your client Id}";
private string subscriptionId = "{your subscription Id}";
//Not needed to set in console app because a function is called to get the token
//string token = "";
public void CreateVD(string name)
{
try
{
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(String.Format(#"https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Web/sites/{2}/config/web?api-version=2015-08-01",subscriptionId,webSpaceName,webSiteName));
request.Headers.Add("x-ms-version", "2013-03-01");
request.ContentType = "application/json";
var token = GetAuthorizationHeader();
request.Headers.Add("Authorization", "Bearer" + " " + token);
System.Net.WebResponse response = request.GetResponse();
string data = "";
using (System.IO.Stream stream = response.GetResponseStream())
{
System.IO.StreamReader sr = new System.IO.StreamReader(stream);
data = sr.ReadToEnd();
sr.Close();
stream.Close();
Console.WriteLine("data found");
}
if (data == "")
{
Console.WriteLine("Error in collecting data");
return;
}
string path = name, directory = name;
data = data.Replace("virtualApplications\":[", "virtualApplications\":[{\"virtualPath\":\"/" + path + "\",\"physicalPath\":\"site\\\\wwwroot\\\\" + directory + "\",\"preloadEnabled\":false,\"virtualDirectories\":null},");
request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(String.Format(#"https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Web/sites/{2}/config/web?api-version=2015-08-01",subscriptionId,webSpaceName,webSiteName));
request.Headers.Add("x-ms-version", "2013-03-01");
request.ContentType = "application/json";
request.AllowWriteStreamBuffering = false;
request.Accept = "Accept=application/json";
request.SendChunked = false;
request.Headers.Add("Authorization", "Bearer" + " " + token);
request.ContentLength = data.Length;
request.Method = "PUT";
System.IO.StreamWriter sw = new System.IO.StreamWriter(request.GetRequestStream());
sw.Write(data);
sw.Close();
response = request.GetResponse();
using (System.IO.Stream stream = response.GetResponseStream())
{
data = (new System.IO.StreamReader(stream)).ReadToEnd();
Console.WriteLine("DONE");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
private string GetAuthorizationHeader()
{
AuthenticationResult result = null;
var context = new AuthenticationContext(string.Format(loginpath, tenantId));
var thread = new Thread(() =>
{
result = context.AcquireToken(apiEndpoint, clientId, new Uri(redirectUri));
});
thread.SetApartmentState(ApartmentState.STA);
thread.Name = "AquireTokenThread";
thread.Start();
thread.Join();
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
}
}
}
This code can be used to create virtual directory from website itself but you cannot use "GetAuthorizationHeader()" method to get the token. Instead you can get the token by running the console app once and use a breakpoint to get the string value. Use this value in the code and remove the "GetAuthorizationHeader()" method.

Categories

Resources