Using MS Graph to Read Excel Contents Through Sharepoint - c#

I'm attempting to use MS Graph to parse the contents of excel files and sync the data with other business-line applications. The issue I'm running into is actually getting at the data in excel.
I'm using a ClientCredentialProvider authenticating to an Azure AD App Registration which has FullControl and Read.All permissions in my tenant to create my GraphServiceClient, and can successfully query the Site via ID, and even see the document library I'm trying to access, but the Items comes up empty. See below
var result = _graphService.Client
.Sites["my-site-id"] // This works
.Drives["site-drive-id"] // This works to find the document library
//.Lists["list-id-corresponding-to-folder"] // This also works to find that folder
.Items // ****This is null****
.Request()
.GetAsync()
.Result;
I tried using the Lists property (as noted above) because as I understand it document libraries in SharePoint are really just lists, but again the Items enumeration yields no results.
I can't find documentation on Microsoft's site on this use case, and I notice using the MS Graph Explorer that the returned object doesn't have an "items" field (or many properties in the Microsoft.Graph.Site class), but I would think there is some way to get this field populated since it's implemented in the Microsoft.Graph namespace. Not sure if I'm missing some permissions step or what, but if I can access the site with FullControl I should be able to access all its contents...
I can't use Client.Me (personal drive) as a source location because 1) the application doesn't run under my permissions and 2) there is a need to read multiple files; the idea would be just provide the needed site/drive/item ID's and get the documents.
Is there some other way I should be going about this?

#broccoli_rob,
MS Graph has not exposed the functionality of enumerating all items in a drive. Instead, you can only list children or get item by id.
We suggest you use /drive/root:/{item-path} to get items in a folder. And you can vaild the endpoint in Graph explorer:
BR

Related

OneDrive SDK (Graph API) Determine if file has been checked out

I am looking for the best way to check if a file has been checked out by a user using the OneDrive SDK. This is just a layer on the Graph API. I wish to prevent downloads in my application if the file is checked out.
I am getting the contents of a folder using this
var results = await graphClient.Drives[driveId].Items[folderId].Children.Request().GetAsync();
However there does not appear to be any properties in this response around if the item is checked out?
From my testing I can attempt to checkout the file anyway and handle an exception is returned if the file is already checked out, but this is not something I would want to do for multiple items for obvious performance reasons.
await graphClient.Drives[driveId].Items[documentId].Checkout().Request().PostAsync();
Is anyone aware of a more efficient way to determine if files are checked out?
You need to read publication property of publicationFacet type. It provides details on the published status of a driveItem resource.
publicationFacet type has property level which describes the state of publication for this document. Either published or checkout.
publication property is not returned by default and must be specified in Select method.
var results = await graphClient.Drives[driveId].Items[folderId].Children
.Request()
.Select("id,...,publication")
.GetAsync();
Documentation
publicationFacet

Microsoft Graph .NET Client Library: Upload file to document center

I want to create a file in a Sharepoint document center using Microsoft Graph .NET Client Library. It seems that I can successfully create the file but it is not visible to anyone except the app which created it. When the app creates a file in an "ordinary" document library with exactly the same code then the file is visible to other users (as expected).
Here is the code I use:
var result = await client.Drives[documentCenterDriveId]
.Items[subfolderId]
.ItemWithPath(fileName)
.Content
.Request()
.PutAsync<DriveItem>(new MemoryStream(buffer));
Afterwards I can query the folder and see that the file is there:
var result = await client.Drives[documentCenterDriveId]
.Items[subfolderId]
.Children
.Request()
.GetAsync();
However when go to the Microsoft Graph Explorer, sign in with my personal credentials (i.e. not the same as the app) and issue the following GET request
https://graph.microsoft.com/v1.0/drives/documentCenterDriveId/items/subfolderId/children
I get an empty list. If I do the same for the "ordinary" document library it works as expected.
I checked the permissions of the file in the document center with
var perms = await client.Drives[documentCenterDriveId]
.Items[fileId]
.Permissions
.Request()
.GetAsync();
and the read role is granted to a group my account belongs to. This means I should be able to see it.
How can I diagnose the source of this issue? Are there logs somewhere in Sharepoint where I could find out more? There are no error messages or exceptions when I run my code.
I found out that I also have to checkin the file.
await client.Drives[documentCenterDriveId].Items[result.Id].Checkin().Request().PostAsync();
I don't know why I do not need to checkin the file after upload in a "ordinary" document library but in the document center I have to.

Get OneDrive items in default sort order

How can I get folder's items in original sort order? I want to get items in the same order as OneDrive folder has online. I have many folders with custom sort arrangements, but I’m always getting items sorted by name only.
var res = Client
.Drive
.Items[FolderId]
.Request()
.Expand("children($expand=thumbnails)")
.GetAsync(); // where FolderId is variable
res.Children always contains items sorted by Name only, no matter what res.Folder.View.SortBy value is.
I'm using Microsoft Graph Client Library.
Do you use OneDrive or OneDrive for Business?
In OneDrive for Business, Graph only supports sorting by name or url. For personal OneDrive, only name, size, and lastModifiedDateTime.
What parameter do you use for sorting when you access your OneDrive with a browser? Is it sorted by date? If so, I'd suggest to add your vote on the Office User Voice

Dynamic CRM new fields

Some new fields were create in Dynamics CRM.
Now need to push some data to those new fields from asp.net website.
Need to add those new fields to:
[assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()]
namespace Xrm
how should this be done? I read that these is a tool that generates this class file (CrmSvcUtil.exe).
But I do not understand how this would work.
Is this something that need to be done through Dynamics CRM admin?
Please advise.
Thanks
This should be done by user which has System Administrator or System Customizer, because this user has to have access to all entities metadata.
Basically you should start with downloading CRM SDK, for your version of CRM. For example the latest SDK can be found here:
https://www.microsoft.com/en-us/download/details.aspx?id=50032
Install the SDK and go to the bin folder inside the folder where you installed it. There you can find crmsvcutil.exe. This tool is something like svcutil.exe - it simply generates proxy classes using CRM metadata service. So instead of referring to Account entity like that:
var account = new Entity("account")
you can simply do:
var account = new Account();
and you will have all the properties that account in your system has.
In order to generate this classes just run crmsvcutil.exe using windows command line with proper credentials (it's very well documented if you run it without any parameters). example usage would be:
crmsvcutil /url:https://orgname.api.crm4.dynamics.com/XRMServices/2011/Organization.svc /u:user#orgname.onmicrosoft.com /p:password /serviceContextName:XrmServiceContext /out:Proxies.cs /n:Xrm
this would generate file Proxies.cs, containing namespace Xrm (the one you have posted in your question) with all the entities and fields. Of course the parameters may vary based on what type of organization you are connecting to. If you have problems with specifying proper values then simply put /il as last command line parameter - it will open an interactive login form, that would make it simpler for you to pass proper connection data.

How do I download documents from AtTask?

I'm working on a continuing API project. The current issue at hand is to be able to download my data from the AtTask server in precisely the folder structure they exist in on the AtTask servers. I've got the folder creation working nicely; the data types between Document, Document Folder and Document Version seem to be pretty clear. I am a little disillusioned about the fact that extension isn't in the document object (that I have to refer to the document VERSION for that)... but I can see some of the reason for that from a design perspective.
The issue I'm running into now is that I need to get the file content. I originally through from the API documentation that I'd be able to get to the file contents the same way as the documentation recommends uploading it -- through the handle. Unfortunately, neither document nor docv seem to support me accessing the handle except to write a new file.
So that leaves me the "download URL" as the remaining option. If I build the UI strings from the API calls using my browser, I get a URL with https://attaskURL/document/download?ID=xxxx (and can also get the versionID and such). If I paste the url into the browser where I'm logged in to the user interface of AtTask, it works fine and I can download the file. If, instead, I use my C# code to do so, I get the login page returned as a stream for me to download instead of my actual file because I'm not authenicated. I've tried creating a network credential and attaching it to the request with the username and password, but to no avail.
I imagine there's a couple ways to solve this problem -- the easy one being finding a way to "log in" to the download site through code (which doesn't seem to be the usual network credential object in C#) OR find a way to access the file contents through the API.
Appreciate your thoughts!
It looks like you can use the download URL if you put a session id in the URL. The details on getting a session id are here (basically just call login and a session id is returned in JSON):
http://developers.attask.com/api-docs/#Authentication
Then cram it on the end of your document download URL:
https://yourcompany.attask-ondemand.com/document/download?ID=xxxx&sessionID=abc1234
I've given this a quick test and I'm able to access a document.
You can use the downloadURL and a sessionID IF you are not using SAML authentication.
I have tried it both ways and using SAML will redirect you to the login page.

Categories

Resources