Creating Azure BlobClient from Uri and connection string - azure-storage

I want to create a Azure SDK BlobClient knowing the blob Uri. I can do it like that :
StorageSharedKeyCredential storageCredential = new StorageSharedKeyCredential("devstoreaccount1", "account key");
BlobClient bl = new BlobClient(new Uri(blobUri), storageCredential);
But I do not want to use the StorageSharedKey in this case. I want to use the connection string.
However the constructor taking a connection string as first parameter looks like this :
Is there another way to initialize the BlobClient with Blob Uri + connection string ? If not, since all I have as input is the Blob Url, is there a way to parse the Url in order to isolate the container name and the blob name ? I don't see how to identify them.

Kind of hacky solution but you can try something like this:
BlobClient blobClient = new BlobClient(new Uri("blob-uri"));
var containerName = blobClient.BlobContainerName;
var blobName = blobClient.Name;
blobClient = new BlobClient(connectionString, containerName, blobName);

Related

Trouble getting a file from Azure container

I am trying to get a file from Azure container. I need to read its content.
The file has been uploaded to umbraco media, media are stored in our Azure container.
Its normal (umbraco) url would be like:
~/media/10890/filename.xls
I am trying to retrieve it like this:
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["strorageconnstring"]);
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("storagemedia");
The thing is - I am not sure how I am supposed to retrieve a particular file? I tried:
1.
CloudBlobDirectory dira = container.GetDirectoryReference("10890"); // file folder within media
var list = dira2.ListBlobs(useFlatBlobListing: true).ToList(); // Returns error saying "The requested URI does not represent any resource on the server."
However the 10890 folder within media storage exists and I can browse it with storage browser.
2.
CloudBlockBlob blobFile = container.GetBlockBlobReference("10890/filename.xls");
string text;
using (var memoryStream = new MemoryStream())
{
blobFile.DownloadToStream(memoryStream); // Throws "The specifed resource name contains invalid characters." error
var length = memoryStream.Length;
text = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
}
Any idea how to read the file? And what am I doing wrong?
Thank You Gaurav for providing your suggestion in comment section.
Thank You nicornotto for confirming that your issue got resolved by changing the container name reference in the below statement.
var container = blobClient.GetContainerReference("storagemedia");

How do I set Set ContentType before upload to azure blob container [duplicate]

This question already has answers here:
How upload blob in Azure Blob Storage with specified ContentType with .NET v12 SDK?
(2 answers)
Closed 2 years ago.
I'm using the asp.net-core webapi to upload images to azure storage.
I was able to successfully upload a image blob to azure storage (using the quickstart). However, the content-type property (with azure) is set to application/octet-stream. The problem with this is the public url will not load in a browser due to this content type. I plan to eventually consume this url/image in my website so I'm thinking this might work. Is there any way to specify the CONTENT-TYPE to image/jpeg? I've also tried the following code but received error message: 404 (The specified blob does not exist.) during the SetHttpHeaders call (the UploadBlob method call that is currently commented out does work, but has the octet-stream content type).
BlobClient blobClient = containerClient.GetBlobClient(guids[index]);
using (var content = file.OpenReadStream())
{
blobClient.Upload(content);
blobClient.SetHttpHeaders(new BlobHttpHeaders() { ContentType = "image/jpeg" });
//containerClient.UploadBlob(guids[index], content);
}
Not specific contentType, with the filename.[ext] download ok. When create the reference to blobclient set the extension. Example download:
var fileName = $"{guids[index]}.jpg";
var pathStorage = Path.Combine(path, fileName);
BlobClient blobClient = containerClient.GetBlobClient(pathStorage);
BlobDownloadInfo download = await blobClient.DownloadAsync();
byte[] bytesContent;
using (var ms = new MemoryStream())
{
await download.Content.CopyToAsync(ms);
bytesContent = ms.ToArray();
}
return bytesContent;
Example upload:
var fileName = $"{guids[index]}.jpg";
var pathStorage = Path.Combine(path, fileName);
BlobClient blobClient = containerClient.GetBlobClient(pathStorage);
var stream = new MemoryStream(bytesContent);
var uploadInfo = await blobClient.UploadAsync(stream);

Azure Data Factory get blob path with sas token in custom activity

I'm trying to build a custom activity in Azure Data Factory that gets a blob as input dataset and would like to pass this blob's sas token path to an API that requires this type of path.
Is there any way to get the blob's path with the sas token in the custom activity?
I figured out a way to do it. Part of the custom activity in ADF v1 is the Execute method that has a context parameter. From that context you can get the connection string to the blob storage and the path of the blob and then you can extract the sas token like this:
public override IDictionary<string, string> Execute(
AOMDotNetActivityContext context,
IActivityLogger logger)
{
string blobConnectionString = context.ConnectionString;
CloudStorageAccount inputStorageAccount = CloudStorageAccount.Parse(blobConnectionString);
var blob = new CloudBlob(new Uri(inputStorageAccount.BlobEndpoint, Path.Combine(context.FolderPath, context.FileName)), inputStorageAccount.Credentials);
SharedAccessBlobPolicy adHocSAS = new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(48),
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Delete
};
string sasBlobToken = blob.GetSharedAccessSignature(adHocSAS);
string fullUri = new Uri(blob.Uri, sasBlobToken).ToString();

Upload a file to Azure Blobservice from a public URI

Is Microsoft planning on to create a method in Azure BlobService that fetches data to the storage from a public URI? Quick google search shows it had something similar in the past, but API is outdated now.
Please have a try to use CloudBlockBlob.StartCopy or CloudBlockBlob.StartCopyAsync,it can work correctly. I write a demo for it.More info about the CloudBlockBlob.StartCopy please refer to the article.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Storage connection string");
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("newcontainer"); //container name
var source = new Uri("public file url");
CloudBlockBlob target = container.GetBlockBlobReference("targe blob name");
target.StartCopy(source);
//or target.StartCopyAsync(source).Wait();
Update:
I did a test with copy blob api, detail info please refer to the screenshot.

How can I do a search with Google Custom Search API for .NET?

I just discovered the Google APIs Client Library for .NET, but because of lack of documentation I have a hard time to figure it out.
I am trying to do a simple test, by doing a custom search, and I have looked among other, at the following namespace:
Google.Apis.Customsearch.v1.Data.Query
I have tried to create a query object and fill out SearchTerms, but how can I fetch results from that query?
My bad, my first answer was not using the Google APIs.
As a pre-requisite, you need to get the Google API client library
(In particular, you will need to reference Google.Apis.dll in your project). Now, assuming you've got your API key and the CX, here is the same code that gets the results, but now using the actual APIs:
string apiKey = "YOUR KEY HERE";
string cx = "YOUR CX HERE";
string query = "YOUR SEARCH HERE";
Google.Apis.Customsearch.v1.CustomsearchService svc = new Google.Apis.Customsearch.v1.CustomsearchService();
svc.Key = apiKey;
Google.Apis.Customsearch.v1.CseResource.ListRequest listRequest = svc.Cse.List(query);
listRequest.Cx = cx;
Google.Apis.Customsearch.v1.Data.Search search = listRequest.Fetch();
foreach (Google.Apis.Customsearch.v1.Data.Result result in search.Items)
{
Console.WriteLine("Title: {0}", result.Title);
Console.WriteLine("Link: {0}", result.Link);
}
First of all, you need to make sure you've generated your API Key and the CX. I am assuming you've done that already, otherwise you can do it at those locations:
API Key (you need to create a new browser key)
CX (you need to create a custom search engine)
Once you have those, here is a simple console app that performs the search and dumps all the titles/links:
static void Main(string[] args)
{
WebClient webClient = new WebClient();
string apiKey = "YOUR KEY HERE";
string cx = "YOUR CX HERE";
string query = "YOUR SEARCH HERE";
string result = webClient.DownloadString(String.Format("https://www.googleapis.com/customsearch/v1?key={0}&cx={1}&q={2}&alt=json", apiKey, cx, query));
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> collection = serializer.Deserialize<Dictionary<string, object>>(result);
foreach (Dictionary<string, object> item in (IEnumerable)collection["items"])
{
Console.WriteLine("Title: {0}", item["title"]);
Console.WriteLine("Link: {0}", item["link"]);
Console.WriteLine();
}
}
As you can see, I'm using a generic JSON deserialization into a dictionary instead of being strongly-typed. This is for convenience purposes, since I don't want to create a class that implements the search results schema. With this approach, the payload is the nested set of key-value pairs. What interests you most is the items collection, which is the search result (first page, I presume). I am only accessing the "title" and "link" properties, but there are many more than you can either see from the documentation or inspect in the debugger.
look at API Reference
using code from google-api-dotnet-client
CustomsearchService svc = new CustomsearchService();
string json = File.ReadAllText("jsonfile",Encoding.UTF8);
Search googleRes = null;
ISerializer des = new NewtonsoftJsonSerializer();
googleRes = des.Deserialize<Search>(json);
or
CustomsearchService svc = new CustomsearchService();
Search googleRes = null;
ISerializer des = new NewtonsoftJsonSerializer();
using (var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
googleRes = des.Deserialize<Search>(fileStream);
}
with the stream you can also read off of webClient or HttpRequest, as you wish
Google.Apis.Customsearch.v1 Client Library
http://www.nuget.org/packages/Google.Apis.Customsearch.v1/
you may start from Getting Started with the API.