I'm looking to at a way to create a folder inside a bucket using the following client library:
https://cloud.google.com/storage/docs/json_api/v1/json-api-dotnet-samples
I've looked at the following thread, and it appears I need to use the simple method upload.
Creating folder in bucket google cloud storage using php
I can't see any way of being able to specify a uploadtype, all requests appear to be uploadType=resumable.
Looking at the above post and a fiddler trace I need to use uploadType=media. Is there away to accomplish this?
It is a bit more straighforward to do this in the latest version of the API.
You still have to make sure that you check for the "/" as Salem has suggested.
public void AddFolder(string folder)
{
StorageClient storageClient = StorageClient.Create();
if (!FolderName.EndsWith("/"))
FolderName += "/";
var content = Encoding.UTF8.GetBytes("");
storageClient.UploadObject(bucketName, folder, "application/x-directory", new MemoryStream(content));
}
This worked for me! Don't know if it's the right way to do it, but there are not enough on this.
public void CreateDir(string FolderName)
{
if (!FolderName.EndsWith("/"))
FolderName += "/";
var uploadStream = new MemoryStream(Encoding.UTF8.GetBytes(""));
Storage.Objects.Insert(
bucket: BucketName,
stream: uploadStream,
contentType: "application/x-directory",
body: new Google.Apis.Storage.v1.Data.Object() { Name = FolderName}
).Upload();
}
EDIT: Just found out that you can directly upload the file to your destination objects, and if the directories/sub-directories don't exist the upload function will create them for you.
All you need to do is put the folder(s) you want before the file name
using (MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(json)))
{
string fileName = $"/test/somefolder/{sourceId}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.json";
await gcpClient.UploadObjectAsync(gcpBucketName, fileName, null, ms);
}
Related
I have an API endpoint that creates files in Google Cloud Storage, and in the end it returns the URI in the gs://bucket_name/file_name format.
How can I write tests in C# to check if the file is indeed created in the cloud? I can download the file with gcutil, but I have not found any library in C# that can handle the gs:// URI to check/download the file.
The official documentation shows how to download objects from buckets
using Google.Cloud.Storage.V1;
using System;
using System.IO;
public class DownloadFileSample
{
public void DownloadFile(
string bucketName = "your-unique-bucket-name",
string objectName = "my-file-name",
string localPath = "my-local-path/my-file-name")
{
var storage = StorageClient.Create();
using var outputFile = File.OpenWrite(localPath);
storage.DownloadObject(bucketName, objectName, outputFile);
Console.WriteLine($"Downloaded {objectName} to {localPath}.");
}
}
Also you can
string fileDownloadPath = #"C:\pathwereyouwanttosavefile\file_Out.pdf";
string objectBlobName = "fileName.pdf";
var gcsStorage = StorageClient.Create();
using var outputFile = File.OpenWrite(fileDownloadPath);
gcsStorage.DownloadObject(bucketName, objectBlobName, outputFile);
Console.WriteLine($"Downloaded {objectBlobName} to {fileDownloadPath}.");
Here you can find more about this implementation
Finally also in the Official documentation shows how to do it with gsutil
gsutil cp gs://BUCKET_NAME/OBJECT_NAME SAVE_TO_LOCATION
You can try to download the object and check for a successful response in order to see if object was created
I'm new to .NET Core and Azure I have created an API with SQL-Server and I used Dapper for saving the path to the database for POST form-data with an image, like this:
private async Task<string> WriteFile(Image image)
{
String fileName;
IFormFile file = image.image;
long Id = image.ShopId;
try
{
var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
fileName = Guid.NewGuid().ToString() + extension;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\cccc", fileName);
using (var bits = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(bits);
}
Image imageupload = new Image(path,Id);
toDb(imageupload);
}
catch (Exception e)
{
return e.Message;
}
return fileName;
}
public void toDb(Image imageUpload)
{
string path = imageUpload.path;
long ShopId = unchecked((int)imageUpload.ShopId);
using (IDbConnection dbConnection = Connection)
{
string sQuery = "UPDATE shop SET path = #path WHERE ShopId = #ShopId ;";
dbConnection.Open();
dbConnection.Execute(sQuery, new {path = path,ShopId = ShopId});
}
}
Before I deployed to Azure it returned image path "F:\\xxxx\\yyyyy\\zzzzzz\\aaaaaa\\wwwroot\\bbbbbb\\5d665cbc-679d-4926-862b-4e10f9358e8a.png"
After i deployed it return my image path
D:\\home\\site\\wwwroot\\wwwroot\\Shops\\a81c757e-df7e-4cf6-b778-20fc5fcf922d.png
can i view image by using this path if it possible how it view;
If the error is my path that file tried to save to how can I fix it? If I changed saved path to wwwroot\\bbbbbb\\5d665cbc-679d-4926-862b-4e10f9358e8a.png can I viewed file it from client app if its also not possible. How can i fixed this?
can i view image by using this path if it possible how it view.
Yes, in the Azure WebApp D:\home is shared for us. We could get more information about Azure WebApp Sandbox from this tutorial.
We could use the Kudu(To access your KUDU console, using your DEPLOYMENT credentials, navigate to https://*****.scm.azurewebsites.net where ***** is the name of your Web App.) to view, upload or download the files.
We also could use the FTP tool to download or upload the files to Azure WebApp site.
can I viewed file it from client app if its also not possible. How can i fixed this?
I recommand that you could store the image information to Azure storge. It is easy for us to access from client side. For more information about how to use Azure Storage, please refer to this document.
Herein lies my problem, the working path to the file I am trying to load into a string variable, when copied from Azure Explorer works fine.
Working: https://container.blob.core.windows.net/files/emailtemplates/EmailMaster.html
When I try to do it via code:
[TestMethod]
public void TestMethod3()
{
string templateHtml;
var blob = AzureStorageMethods.GetAzureBlob(AzureFileFolder + "EmailMaster.html");
using (var memoryStream = new MemoryStream())
{
blob.DownloadToStream(memoryStream);
templateHtml = Encoding.UTF8.GetString(memoryStream.ToArray());
}
Assert.AreNotEqual(0, templateHtml.Length);
}
Here is the code for GetAzureBlob:
public static CloudBlockBlob GetAzureBlob(string filename)
{
var creds = ConfigurationManager.AppSettings["azurestorageconn"];
var storageAccount = CloudStorageAccount.Parse(creds);
var client = storageAccount.CreateCloudBlobClient();
//create a blob container and make it publicly accessibile
var sampleContainer = client.GetContainerReference(ConfigurationManager.AppSettings["azurecontainer"]);
sampleContainer.CreateIfNotExists();
sampleContainer.SetPermissions(new BlobContainerPermissions()
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
var blob = sampleContainer.GetBlockBlobReference(#"files\" + filename);
return blob;
}
It fails to Download the stream because the endpoint path is wrong.
It comes back as
Not Working: https://container.blob.core.windows.net/container/files/emailtemplates/EmailMaster.html
Note that my method to return a blob, has the container as part of the url, whereas the path from azure explorer does not.
I can't see any way to solve this. I've tried accessing the files container directly but I'm either doing it wrong or it isn't doable.
The directory tree (even though there technically isn't one in Azure) is mystorageaccountname/files/emailtemplates/filename. Any solutions appreciated.
Please change this line of code:
var blob = sampleContainer.GetBlockBlobReference(#"files\" + filename);
to
var blob = sampleContainer.GetBlockBlobReference(filename);
Based on your note:
The directory tree (even though there technically isn't one in Azure)
is mystorageaccountname/files/emailtemplates/filename.
It is my understanding that the name of your container is files. When you use container.GetBlockBlobReference construct, you don't need to specify the container name again in the name parameter. It will be taken care of by the library.
We are using Kentico v9 and are importing blog posts from Wordpress into Kentico. We are having a problem importing the attachments into the blog post. Here's the code currently being used:
var attachmentNode = TreeNode.New(FILE_PAGE_TYPE);
attachmentNode.DocumentName = filename;
attachmentNode.DocumentCulture = postNode.DocumentCulture;
attachmentNode.Insert(postNode);
DocumentHelper.AddAttachment(attachmentNode, "ce4c5d10-c143-4ada-9d8a-7e7481b167ef", localFileLocation, postNode.TreeProvider);
attachmentNode.Update();
This does not produce any error, and there is a record in the database for the file. However, the file itself is not in Kentico. Does anyone know what I'm doing wrong here?
See the answer I provided in the Kentico DevNet.
TreeNode newNode = TreeNode.New(PageType, tree);
newNode.DocumentName = mediaFile.FileName;
newNode.DocumentName = fileName.Trim();
newNode.SetValue("FileDate", fileDate);
DocumentHelper.InsertDocument(newNode, parentNode.NodeID);
AttachmentInfo newAttachment = null;
// Path to the file to be inserted. This example uses an explicitly defined file path. However, you can use an object of the HttpPostedFile type (uploaded via an upload control).
string filePath = MediaLibraryPath + #"\" + mediaFile.FileName + mediaFile.FileExtension;
// Insert the attachment and update the document with its GUID
newAttachment = DocumentHelper.AddUnsortedAttachment(newNode, Guid.NewGuid(), filePath, tree, ImageHelper.AUTOSIZE, ImageHelper.AUTOSIZE, ImageHelper.AUTOSIZE);
// attach the new attachment to the page/document
newNode.SetValue("FileAttachment", newAttachment.AttachmentGUID);
DocumentHelper.UpdateDocument(newNode);
newNode.Publish();
I don't think this code does any operation/processing of an actual file - it just saves a reference to that file into a database. If you want to save it in particular location in your file system you have to implement appropriate functionality.
See some examples of API working with attachments.
I need a method which will take an *.jpg image file and upload it to a user profile in the Active Directory of Windows AD 2003.
Also a method to retrieve the photo as stream or expose it as secure web service to be called by cross platform apps in java etc (Damn! am I asking too much!!!)
The file being uploaded will be a *.jpg which is basically a visual signature file created by a user.
Does anyone having any experience working with Active Directory in C# provide some information as to how this can be done with minimum implication related to security.
From the point of view of the Windows Active Directory Administrator what does he have to
do to make this possible.Changes/provisions to schema of user profile etc.
The image is being uploaded so that it can be later retrieved from the AD to be inserted into PDF document for signature purposes.
Can this be done in C#? Or is there any done libraries etc?
Here's a series of blog postings with code that shows how to do it:
(The first shows how to get a photo in, the second shows how to get it out)
Using the jpegPhoto attribute in AD - Part I
Using the jpegPhoto attribute in AD - Part II
EDIT: Here's a generic function implementing the code from Part I:
void AddPictureToUser(
string strDN, // User Distinguished Name, in the form "CN=Joe User,OU=Employees,DC=company,DC=local"
string strDCName, // Domain Controller, ie: "DC-01"
string strFileName // Picture file to open and import into AD
)
{
// Open file
System.IO.FileStream inFile = new System.IO.FileStream(strFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
// Retrive Data into a byte array variable
byte[] binaryData = new byte[inFile.Length];
int bytesRead = inFile.Read(binaryData, 0, (int)inFile.Length);
inFile.Close();
// Connect to AD
System.DirectoryServices.DirectoryEntry myUser = new System.DirectoryServices.DirectoryEntry(#"LDAP://" + strDCName + #"/" + strDN);
// Clear existing picture if exists
myUser.Properties["jpegPhoto"].Clear();
// Update attribute with binary data from file
myUser.Properties["jpegPhoto"].Add(binaryData);
myUser.CommitChanges();
}
EDIT: I found that in my organisation, the correct attribute to set was "thumbnailPhoto" like this:
myUser.Properties["thumbnailPhoto"].Add(binaryData);
This also seems to tbe the one that the commercial product Exclaimer is setting (but it might be only doing that in my organization)
The common AD attribute for a user photo is jpegPhoto but you can use what ever name you want
This sample shows the basic AD way to get and set an image stream. You need to flesh these methods out to be a useful class
Consider making your web service to just return the URL of the image. The request handler for that URL should then return the image with the correct content type etc. Much more useful in a web environment
using System;
using System.DirectoryServices;
using System.Collections;
using System.IO;
public class ADPhoto {
public void Set() {
try {
var de = new DirectoryEntry("LDAP://cn=username,cn=users,DC=domain, DC=com");
de.Username = "username";
de.Password = "password";
var forceAuth = de.NativeObject;
var fs = new FileStream("path\\photo.jpg", FileMode.Open);
var br = new BinaryReader(fs);
br.BaseStream.Seek(0, SeekOrigin.Begin);
byte[] ba = new byte[br.BaseStream.Length];
ba = br.ReadBytes((int)br.BaseStream.Length);
de.Properties["jpegPhoto"].Insert(0, ba);
de.CommitChanges();
}
catch(Exception ex) {
Console.WriteLine(ex.Message);
}
}
public Stream Get() {
var fs = new MemoryStream();
try {
var de = new DirectoryEntry("LDAP://cn=username,cn=users,DC=domain, DC=com");
de.Username = "username";
de.Password = "password";
var forceAuth = de.NativeObject;
var wr = new BinaryWriter(fs);
byte[] bb = (byte[])de.Properties["jpegPhoto"][0];
wr.Write(bb);
wr.Close();
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
return fs;
}
}
Found an article that describes how to upload pictures to Active Directory and how to get them to show on the end-users computers.
http://blog.jocha.se/tech/ad-user-pictures-in-windows-10
Each Active Directory User Profile will have a home folder.
If you are not sure about this please checkout the below article
http://support.microsoft.com/kb/816313
I believe that you have to upload the image file to this directory.
Also if this doesn't solve your problem, please update if you find something else.
MNK...