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

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

Related

Dropbox.net get user favorite folder content

I need to know if its possible to list folders and files in "Starred" section of Dropbox? I've tried to get the path "/starred", "starred", "/starred/" or "starred/", but I get an exception that the path is invalid.
ListFolderResult listOfFolderItems = await dropboxClient.Files.ListFolderAsync("/starred");
The Dropbox API unfortunately doesn't offer the ability to get starred files, but I'll pass this along as a feature request. I can't promise if or when that might be implemented though.

Using MS Graph to Read Excel Contents Through Sharepoint

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

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.

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.

Lync - inconsistent behavior with ContactEndpoints

I'm working on custom UI for company's directory based on Lync. Using Lync 2013 I execute this search:
Container.Instance.Lync.ContactManager.BeginSearch(SearchQuery,
SearchProviders.GlobalAddressList,
SearchFields.AllFields,
SearchOptions.IncludeContactsWithoutSipOrTelUri,
500,
ContactsAndGroupsCallback, SearchQuery);
For each of matching contacts I try to access their endpoints to display phone number:
var cit = ContactInformationType.ContactEndpoints;
var endpoints = contact.GetContactInformation(cit) as List<object>;
Problem
If found contact is in the contact list of account I'm using to connect Lync, then I get access to full details (5 endpoints). However if he is not in contact list, I get access to only 1 endpoint.
Any ideas why is it happening like that? Is there a global privacy setting I need to turn off or something?
How can I get access to all endpoints at all times?
Thank you.
PS: I tried to load each contact in the result set individually and still get the same behavior.
I encountered a similar problem when trying to write a program to obtain the status of all users on Lync SDK 2010. Chose all users and read it's status (online / offline etc.). But it's working out well with only those contacts that were in the list of client contacts. I do not know why, but the solutions are not found.A little later I use UCMA 4 (with Application endpoint), though the list received from AD and only able to get the current status.
Maybe it makes sense to use the search by AD? Find phone number by user sip? If so, try to use this filter for DirectorySearcher:
searcher.Filter = "(&(objectClass=user)(msRTCSIP-PrimaryUserAddress=*))"; //put sip instead of *
P.S. what sdk are you using?
Answer from Microsoft Support:
The behavior you are seeing is due to presence subscription optimization to the Lync client so that the subscription is delayed until the necessary contact information is required by the Lync client. Photo is an example for this optimization. Another example is ContactEndpoints. Please take a look at Contact presence subscription changes section of the Migration doc for Lync 2013 page in MSDN docs.
Specifically you must create and maintain your own ContactSubscription for the contacts that you need all the ContactEndpoints.
I have been facing the same issue. You can try loading the person's ContactCard before calling the GetContactInformation function explicitly
Microsoft.Lync.Controls.ContactCard objContactCard = new Microsoft.Lync.Controls.ContactCard();
objContactCard.Source=objContact.GetContactInformation(ContactInformationType.EmailAddresses);
ContactSubscription _contactSubscription = lyncObj.ContactManager.CreateSubscription();
_contactSubscription.AddContact(foundContact);
_contactSubscription.Subscribe(ContactSubscriptionRefreshRate.High, _ContactInformationList);
However, you still might get some delay in getting the information (phone numbers). You can choose to use Thread.Sleep or might just want to retry.
Hope this helps.
Problematic is relying on contact information even for the lync client user. In our solution we are doing something like this:
Contact user = LyncClient.GetClient().Self.Contact;
string email = user.GetContactInformation(ContactInformationType.PrimaryEmailAddress) as string;
I would expect that the current lync user contact always is filled properly. And if it wasn't, I'd expect the code to throw an exception or at least return null or an empty string.
Instead it sometimes returns the sip-uri of the contact without the leading "sip:" prefix. Oddly enough this is not always reproducable: Most of the time the code above returns the primary email address (according to active directory) correctly, sometimes it behaves as mentioned above.

Categories

Resources