How to access Box folder shared with me using C# SDK - c#

Someone has shared a Box.com folder with me using the link. I need to be able to use the C# SDK or REST API to download the documents from their folder.
I have tried all 3 authentication types and have attempted to access with both the C# SDK and REST API.
//SDK attempt
var findFolder = await client.SharedItemsManager.SharedItemsAsync("https://<userWhoSharedWithMe>.box.com/s/<folderHash>"); // notFound
var folder = await client.FoldersManager.GetInformationAsync(findFolder.Id);
var items = folder.ItemCollection;
//API Attempt
var client = new HttpClient
{
BaseAddress = new Uri("https://api.box.com")
};
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<bearerToken>");
var response = await client.GetAsync("2.0/folders/<folderId>/items");
var content = await response.Content.ReadAsStringAsync();
Is there any way to programmatically download documents from a box folder that was shared with me via link?
-- Edited 06/04/2019
The folder owner and I have tried various things and it seems the API still will not allow me to see the content of the shared folder. Is there anything the folder owner needs to do to make it visible?

Based on the suggestion that I received from a Box employee, I made the following changes.
First the snippet that didn't work as expected:
// DOES NOT WORK
var reader = new StreamReader("box-config.json");
var json = reader.ReadToEnd();
var config = BoxConfig.CreateFromJsonString(json);
var sdk = new BoxJWTAuth(config);
var token = sdk.AdminToken();
var session = new OAuthSession(token, "N/A", 3600, "bearer");
boxClient = new BoxClient(config, session, asUser: boxUserId);
Secondly, the modified version that worked, allowing me to see the folder that was shared to me and allowed me to traverse its contents:
// THIS WORKS !!!!!!!!
var reader = new StreamReader("box-config.json");
var json = reader.ReadToEnd();
var config = BoxConfig.CreateFromJsonString(json);
var sdk = new BoxJWTAuth(config);
var token = sdk.UserToken(boxUserId);
boxClient = sdk.UserClient(token, boxUserId);
And for completeness' sake, here's a snippet of code that will allow you to programmatically access a Box folder and traverse its contents:
//folderId <-- You can find this ID by logging into your box account and navigating to the folder that you're interested in accessing programmatically.
var items = await boxClient.FoldersManager.GetFolderItemsAsync(folderId, limit: 5000, offset: 0, autoPaginate: false,
sort: "name", direction: BoxSortDirection.DESC);
// How many things are this folder?
Console.WriteLine($"TotalCount: {items.TotalCount}");
// Loop through those items
foreach (var item in items.Entries)
{
// Get info on each item
var file = await boxClient.FilesManager.GetInformationAsync(item.Id);
// Print the filename
Console.WriteLine($"file: {item.Name}");
}

Related

Add Power Point to existing folder within SharePoint

I have some function (shown below that works as expected) that creates a SharePoint folder. For simplicity sake we can ignore the operation of creating a folder and assume the folder already exists within the SharePoint site...
I am curious as to how to open a given folder using the API and add a file to it that is a PowerPoint. The purposes of the PowerPoint is that each newly created folder will contain a template PowerPoint which can then be copy/changed by the user removing the need for the user to download the template themselves and add the PowerPoint to the folder manually.
For simplicity as mentioned earlier we can assume the folder already exists so I would just need to access it using
var sharepoint = await graphClient.Sites.GetByPath("/sites/SiteFolder", "localhost.sharepoint.com").Request().GetAsync();
Then perform a similar Add operation that is being used to create a new folder.
I know I'd either need to read the binary data from the PowerPoint and pass that to some File object or if there's a simpler way to use the direct link to the template PowerPoint and simply create a copy of it and insert it into the SharePoint folder.
public async Task<string> Sharepoint_FolderCreate(string NewFolderName, string sharepoint_folder_path = "/SomeFolderPath")
{
var item = new DriveItem
{
Name = NewFolderName.Replace("?", " ").Replace("/", " ").Replace("\\", " ").Replace("<", " ").Replace(">", " ").Replace("*", " ").Replace("\"", " ").Replace(":", " ").Replace("|", " "),
Folder = new Folder { },
AdditionalData = new Dictionary<string, object>()
{
{"#microsoft.graph.conflictBehavior","rename"}
}
};
var scopes = new[] { "https://graph.microsoft.com/.default" };
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
tenantID, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var sharepoint = await graphClient.Sites.GetByPath("/sites/SiteFolder", "localhost.sharepoint.com").Request().GetAsync();
await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath(sharepoint_folder_path).Children.Request().AddAsync(item);
var NewFolder = await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath($"{sharepoint_folder_path}/{item.Name}").Request().GetAsync();
return NewFolder.WebUrl;
}

Issues publishing image to Facebook Page via Graph API SDK .NET

Attempting this on .NET Core 3.1
After several hours of trying to publish a photo to my public facebook page (as in business page) of which I am the admin and have a long-term token for...
I keep getting the following response to my request using the official Facebook SDK for .NET. However, the image itself is never loaded.
{{"id":"786692942226147","post_id":"113260773923227_786692942226147"}}
The request looks like
var imageMedia = new FacebookMediaObject { FileName = file.FileName, ContentType = file.ContentType };
var stream = file.OpenReadStream();
var bytes = await stream.ReadAsByteArrayAsync();
imageMedia.SetValue(bytes);
var fbClient = new FacebookClient(credential.Token)
{
AppId = _config.GetValue<string>("FacebookClientId"),
AppSecret = _config.GetValue<string>("FacebookSecret")
};
dynamic parameters = new ExpandoObject();
parameters.message = request.Message;
parameters.file = imageMedia;
var result = await fbClient.PostTaskAsync($"{credential.PageId}/photos", parameters, token);
I'm sure it has something to do with the parameters I'm passing in, like parameters.file... but the docs for this thing are VERY unclear... as in "literally does not exist"
Anyone with experience getting this working, please point me in the right direction?
The solution is to change parameters.file to parameters.image...

Extracting ListItems from a List in a SharePoint Site

I am trying to extract a list of items in a SharePoint Site below the root site at host.sharepoint.com/sites/mysite. I've tried a bunch of different methods, but only one seems to work:
var host = "host.sharepoint.com:/";
var siteName = "mysite";
var listName = "MyList";
// Generate the Client Connection
var graphHelper = new ApplicationAuthenticatedClient(ClientId, Tenant, ClientSecret);
await graphHelper.ConnectAsync().ConfigureAwait(false);
// Code: itemNotFound
//Message: The provided path does not exist, or does not represent a site
//var list = await graphHelper.GraphClient.Sites[$"{host}{siteName}"].Request().GetAsync();
// Returns a Site, no Lists.
//var list = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().GetAsync();
//Code: itemNotFound
//Message: The provided path does not exist, or does not represent a site
//var list = await graphHelper.GraphClient.Sites[host].Sites[siteName].Lists[listName].Request().GetAsync();
// List retrieved, but no Items
//var site = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().Expand("lists").GetAsync();
//var list = await graphHelper.GraphClient.Sites[site.Id].Lists[listName].Request().Expand("Items").GetAsync();
//Code: invalidRequest
//Message: Can only provide expand and select for expand options
//var queryOptions = new List<QueryOption>() { new QueryOption("expand", "fields") };
// This works
var site = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().GetAsync();
var list = await graphHelper.GraphClient.Sites[site.Id].Lists[listName].Items.Request().Expand("Fields").GetAsync();
I've finally managed to get it to connect, but I'm wondering if there's a better way to navigate to the list, rather than the two API calls? (Assuming that I don't know the Site ID beforehand)
Edit: Using the Graph Explorer, I can access the items using https://graph.microsoft.com/v1.0/sites/{host}.sharepoint.com:/sites/{siteName}:/lists/{listName}/items?expand=fields, but I don't know how to (or if) access that API call in a single call in the .NET API.
It appears that I was on the right track with var list = await graphHelper.GraphClient.Sites[$"{host}{siteName}"].Request().GetAsync(); but the URI was not formatted correctly.
The correct Site ID for https://host.sharepoint.com/sites/mysite/MyList is:
Sites[host.sharepoint.com:/sites/mysite:"]
Retrieving the list from the code in my original question would look like this:
var host = "host.sharepoint.com";
var siteName = "mysite";
var listName = "MyList";
// Generate the Client Connection
var graphHelper = new ApplicationAuthenticatedClient(ClientId, Tenant, ClientSecret);
await graphHelper.ConnectAsync().ConfigureAwait(false);
var list = await graphHelper.GraphClient.Sites[$"{host}:/sites/{siteName}:"].Lists[listName].Request().GetAsync();
it's possible in one API call.
GET https://graph.microsoft.com/v1.0/sites/{host}.sharepoint.com:/sites/{siteName}:/lists/{listTitle}/items?$expand=Fields

C# Authentication error in google dialogflow API

How do i fix this. I want to set my authentication in my code and not on the machine.
I have checked almost every answer on stackoverflow and github, but none has a good explanation.
How do i pass the credentials to the create intent, it throws this error.
InvalidOperationException: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
GoogleCredential credential =
GoogleCredential.FromFile(file);
//var credential = GoogleCredential.FromStream(
// Assembly.GetExecutingAssembly().GetManifestResourceStream("chatbot-a90a9-8f2fb910202d.json"))
// .CreateScoped(IntentsClient.DefaultScopes);
var storage = StorageClient.Create(credential);
var client = IntentsClient.Create();
var text = new Intent.Types.Message.Types.Text();
text.Text_.Add("Message Text");
var message = new Intent.Types.Message()
{
Text = text
};
var trainingPhrasesParts = new List<string>
{
"Book a fligt",
"check cheap flights"
};
var phraseParts = new List<Intent.Types.TrainingPhrase.Types.Part>();
foreach (var part in trainingPhrasesParts)
{
phraseParts.Add(new Intent.Types.TrainingPhrase.Types.Part()
{
Text = part
});
}
var trainingPhrase = new Intent.Types.TrainingPhrase();
trainingPhrase.Parts.AddRange(phraseParts);
var intent = new Intent();
intent.DisplayName = "test";
intent.Messages.Add(message);
intent.TrainingPhrases.Add(trainingPhrase);
var newIntent = client.CreateIntent(
parent: new AgentName("chatbot-a90a9"),
intent: intent
);
SOLVED.
I change
var client = IntentsClient.Create();
To
IntentsClientBuilder builder = new IntentsClientBuilder
{
CredentialsPath = file, // Relative to where the code is executing or absolute path.
// Scopes = IntentsClient.DefaultScopes // Commented out because there's no need to specify this since you are using the defaults and all default values will be automatically used for values not specified in the builder.
};
IntentsClient client = builder.Build();

Need to create a folder(and a file inside it) using C# inside Azure DevOps repository - be it Git or TFVC

From Azure DevOps portal, I can manually add file/ folder into repository irrespective of the fact that source code is cloned or not - Image for illustration.
However, I want to programmatically create a folder and a file inside that folder within a Repository from c# code in my ASP .NET core application.
Is there a Azure DevOps service REST API or any other way to do that? I'll use BASIC authentication through PAT token only.
Note : I'm restricted to clone the source code at local repository.
Early reply is really appreciated.
I tried HttpClient, GitHttpClient and LibGit2Sharp but failed.
Follow below steps in your C# code
call GetRef REST https://dev.azure.com/{0}/{1}/_apis/git/repositories/{2}/refs{3}
this should return the object of your repository branch which you can use to push your changes
Next, call Push REST API to create folder or file into your repository
https://dev.azure.com/{0}/{1}/_apis/git/repositories/{2}/pushes{3}
var changes = new List<ChangeToAdd>();
//Add Files
//pnp_structure.yml
var jsonContent = File.ReadAllText(#"./static-files/somejsonfile.json");
ChangeToAdd changeJson = new ChangeToAdd()
{
changeType = "add",
item = new ItemBase() { path = string.Concat(path, "/[your-folder-name]/somejsonfile.json") },
newContent = new Newcontent()
{
contentType = "rawtext",
content = jsonContent
}
};
changes.Add(changeJson);
CommitToAdd commit = new CommitToAdd();
commit.comment = "commit from code";
commit.changes = changes.ToArray();
var content = new List<CommitToAdd>() { commit };
var request = new
{
refUpdates = refs,
commits = content
};
var personalaccesstoken = _configuration["azure-devOps-configuration-token"];
var authorization = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalaccesstoken)));
_logger.LogInformation($"[HTTP REQUEST] make a http call with uri: {uri} ");
//here I making http client call
// https://dev.azure.com/{orgnizationName}/{projectName}/_apis/git/repositories/{repositoryId}/pushes{?api-version}
var result = _httpClient.SendHttpWebRequest(uri, method, data, authorization);

Categories

Resources