How do I get the parent folder using the Google Drive API? - c#

I'm trying to write a method that gets the parent folder of the folder whose Id is passed in. I have tried many different variations, most of which come from accepted answers here, but every one causes an exception.
For example, the following code...
public async Task<DriveFile> GetParentFolder(string folderId) {
FilesResource.ListRequest request = _service.Files.List();
request.Q = $"parents contains '{folderId}'";
request.Fields = "*";
FileList files = await request.ExecuteAsync();
return files.Files[0];
}
...throws the following exception...
Error: The service drive has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError
Invalid Value [400]
Errors [
Message[Invalid Value] Location[q - parameter] Reason[invalid] Domain[global]
]
I have tried many values for the Q and Fields properties, but all result in the same exception.
I have other code working with the API, so it's not the basic service that's a problem, and I've used the API to get the Ids of some folders, so I know I'm passing in a valid value.
One of the problems is that v2 of the API had a Parents list, which looks like it does what I want, but this seems to be missing in v3.
Anyone able to help me? Thanks

Your going about it the wrong way you dont need to use file.list you already have the file id just use file.get.
Lets say i have the folder id here.
{
"kind": "drive#file",
"id": "1bzDkXlcND_yycIcbqwr1YYZ98-Yv7SG7",
"name": "Current Badges (2019-21)",
"mimeType": "application/vnd.google-apps.folder"
},
As you can see in this example i have the id and the mime type is a folder.
All i need to do is do a file.get
var request = _service.Files.Get("1bzDkXlcND_yycIcbqwr1YYZ98-Yv7SG7");
request.Fields = "parents";
var response = request.Execute();
The response will contain a filed called parents which is the parent of the folder.
As you can see if you already know the file id or in this case the folder id. Then you really just need to use file.get to get all the information about that id.
There's really no reason to use file.list.

Related

Azure Function - "PartitionKey extracted from document doesn't match the one specified in the header" on container created in portal

I'm trying to upload some data into Azure Cosmos Db container via CreateItemAsync() method, with this code:
Database partnersDb = GetCosmosDb();
Container partnersContainer = GetCosmosContainer(partnersDb);
try
{
ItemResponse<PartnerInfo> partnersResponse = await partnersContainer.CreateItemAsync(partner, new PartitionKey(partner.Id));
}
catch (CosmosException e) when (e.StatusCode == HttpStatusCode.Conflict)
{
logger.LogInformation($"Item with id {partner.Id} already exists in partners database");
}
The problem is, that upon trying to upload, i get "PartitionKey extracted from document doesn't match the one specified in the header" error mentioned in the title. I've read similar topics about this, and wasn't able to find out what's wrong. I'm trying to pass value as partitionKey that is defined as [JsonProperty(PropertyName = "id")], moreover, container I'm trying to upload into has been created by someone in azure portal, and I do not know what PartitionKey is specified. Upon trying to run
select c.partitionkey from c
In cosmos db, i get only this for 3 items that have been created manually via "New item" option:
[
{},
{},
{}
]
Any ideas?
This error causes by two value of PartitionKey(within your document and CreateItemAsync method) are not same.
You can get PartitionKeyPath by using this code
ContainerProperties properties = await container.ReadContainerAsync();
Console.WriteLine(properties.PartitionKeyPath);
Then pass the value of the same name that was after slash '/' as a partitionKey to CreateItemAsync method can solve this error.

The site in the encoded share URI is invalid

I've tried to use Microsoft Graph to pull some files from a shared link. However, when I try to do that using the Microsoft Graph Explorer, it returns:
"error": {
"code": "invalidRequest",
"message": "The site in the encoded share URI is invalid.",
"innerError": {
"request-id": "e07b0df4-88e0-49fd-97e4-eccaaf887d6e",
"date": "2019-11-29T19:05:52"
}
}
The encoding code is this(same as on the docs):
string base64Value =
Convert
.ToBase64String(UTF8
.GetBytes("https://1drv.ms/f/s!An8UzxYP03zbg5lyUW0nVFclockIaw"));
string encodedUrl = "u!" +
base64Value.TrimEnd('=')
.Replace('/', '_')
.Replace('+', '-');
The link is in the code and goes to an empty shared folder (for testing purposes).
i had the same problem, turned out i wasn't logged into graph under my account
derp.
UPDATE
Soo, a couple of months have passed and I have managed to fix my problem:
How did I do it?
TLDR: The share URI isn't extracted as MS tells you (for whatever reason)
Let's take my example folder:
https://1drv.ms/f/s!An8UzxYP03zbg5lyUW0nVFclockIaw
In this case, the URI is everything after(including)the "s" part, so in my case it's s!An8UzxYP03zbg5lyUW0nVFclockIaw
CODE
private static string GetIDFromLink(string website)
{
return "s!" + website.TrimStart("https://1drv.ms/f/".ToCharArray());
}
Don't forget that you MUST be logged in to MSGraph and have the proper permission to access files
Also, if you're using the "Application Daemon" method(aka, no user sign-in) you must have a SharePoint 365 subscription active(at least from what I've observed, I would like to be wrong on that)

SCIM Deserialization Issue in .NET

As a newcomer to the SCIM (System for Cross-domain Identity Management) standard, please excuse any ignorance as I'm on the learning curve trying to figure out how to make clean/simple requests to provision users, delete users and modifiy users.
I'm attempting to use C#/.NET to make HTTP REST requests for a user via SCIM, using the System.Net.Http.HttpClient
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx
I can do this successfully and get a JSON response from the server, however in order to easily read the response object and manipulate it, I want to deserialize it.. After much reading around trying to use things like JsonConvert, dynamic etc. I stumbled upon a Microsoft nuget library which seemed to hint at being useful. Sadly there don't appear to be any docs for it*
UPDATED:
One of the authors has updated the nuget page with a link to a blog post which goes some way to explaining usage.
Microsoft.SystemForCrossDomainIdentityManagement
https://www.nuget.org/packages/Microsoft.SystemForCrossDomainIdentityManagement/
The SCIM provider I'm attempting to get data from is Facebook, using the example they publish on their site for getting a user by email:
https://developers.facebook.com/docs/facebook-at-work/provisioning/scim-api#getuserbyemail
Here's a code sample in C# which attempts to get the user from the SCIM service and deserialize them. I'm finding that the queryResponse I get back is deserialized correctly as the properties are populated, however the Core1EnterpriseUser which is the first and only of the resource objects, has null/default properties.
var userName = "foo.bar#foobar.com";
var response = await client.GetAsync($"Users?filter=userName%20eq%20%22{userName}%22");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var jsonResponseProperties = await Task.Factory.StartNew(() => { return JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
var userFactory = new QueryResponseJsonDeserializingFactory<Core1EnterpriseUser>();
var queryResponse = userFactory.Create(jsonResponseProperties);
if (queryResponse.TotalResults == 1)
{
var user = queryResponse.Resources.First();
var id = user.Identifier; // this and other properties are null/false etc.
}
}
Here's a sample of the JSON that is returned by the service when I query it:
{
"schemas": [
"urn:scim:schemas:core:1.0"
],
"totalResults": 1,
"itemsPerPage": 10,
"startIndex": 1,
"Resources": [
{
"schemas": [
"urn:scim:schemas:core:1.0",
"urn:scim:schemas:extension:enterprise:1.0",
"urn:scim:schemas:extension:facebook:starttermdates:1.0",
"urn:scim:schemas:extension:facebook:suppressclaimemail:1.0"
],
"id": 180383108978226,
"userName": "foo.bar\u0040foobar.com",
"name": {
"formatted": "Foo Bar",
"familyName": "Bar",
"givenName": "Foo"
},
"title": "Vice President",
"active": true,
"emails": [
{
"primary": false,
"type": "work",
"value": "foo.bar\u0040foobar.com"
}
],
"urn:scim:schemas:extension:enterprise:1.0": {
"department": "IT"
},
"urn:scim:schemas:extension:facebook:starttermdates:1.0": {
"startDate": 0,
"termDate": 0
}
}
]
}
UPDATE:
I'm in dialog with one of the authors of the project and he kindly pointed me at this blog post:
http://blogs.technet.com/b/ad/archive/2015/11/23/azure-ad-helping-you-adding-scim-support-to-your-applications.aspx
He has also updated the nuget library which now includes support for v1 of SCIM, also pointing out that as the JSON data suggests the version used by Facebook is v1: "urn:scim:schemas:core:1.0" so now I can use Core1 rather than attempting to use Core2 classes (I've updated the question above to use Core1EnterpriseUser).
I'm still not able to get my response deserialized correcty at present and will update the question with more information as I have it.
Again, I don't have to use this library if it becomes apparent that it's not easily going to work, as I know the brief description on nuget suggests it was created for Azure AD.
However I'd appreciate any advice on how this type of thing could/should be done as I'm sure there must be a lot of people out there using SCIM - how do you parse your responses/generate your requests such that you have actual objects? Can you automatically parse responses for schemas in order to augment the object with the correct properties?
I was up late last night hand crafting some model classes to handle the response objects - which I do seem to have working. If I can't get the nuget library working (the preferred option) then I'll have to go with my own. :/
Thanks again
peteski
Although I'm still none the wiser about best practices with SCIM, I've managed to get the code working now - with massive thanks to one of the nuget library's authors Craig McMurtry at Microsoft!
There were a few things to iron out along the way, such as the nuget package being updated to include the previous support for older v1 SCIM objects. But here's a snippet of what worked based on the example in my question, but it turned out to be using the Newtonsoft serializer. :(
In the code above the line:
var jsonResponseProperties = await Task.Factory.StartNew(() => { return JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
Was replaced with:
var jsonResponseProperties = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Et voilĂ ! My object's properties are now deserializing...

Facebook API - getting friend list with detail info again

I'm using Facebook SDK ( http://facebooksdk.net ) and want to get friend list with the following information:
1. ID
2. Name
3. Photo
4. link
5. Email
6. etc...
I have read Facebook's documentation and different posts of forum (including stackoverflow), but I'm confused. After it I'm not sure, is it possible to get this information by API request or not. First at all, this request returns only ID and name data:
var client = new FacebookClient("XXX");
dynamic friends = client.Get("/me/friends");
Next step - try to modify this request to specify returned fields:
var client = new FacebookClient("XXX");
dynamic friends = client.Get("/me/friends?fields=about,bio,age_range,first_name,gender,address,email,location,link,languages,username,last_name,timezone,updated_time");
it returns only some fields:
"first_name": "XXX",
"gender": "male",
"link": "https://www.facebook.com/XXX",
"username": "XXX",
"last_name": "XXX",
"updated_time": "2013-09-07T12:18:34+0000",
"id": "XXX"
is it possible to return more fields? As I understood, it depends on permissions. I try to set these permissions. I go to Applications -> MyApp -> Permissions, and see, that field "User & Friend Permissions" is empty. I try to set some permissions, i.e.
user_about_me,friends_about_me
and after click "Save" button I see the message:
Changes saved. Note that your changes may take several minutes to
propagate to all servers.
but field "User & Friend Permissions" is empty again. First question : why and how can I see all set permissions?
secondly - I don't see any changes in my request via FacebookClient (but field "About" is added to request). Why?
Thanks
The fields that you can get without any extra permissions:
first_name
gender
link
username
last_name
updated_time
id
With permissions-
friends_about_me - about, bio
friends_location - location
friends_likes - languages
Invalid fields (I don't know from where you saw these)-
age_range
address
email
timezone
Another thing that you are not getting all the fields is because the permissions are not being asked by the user (and hence not granted any to your app).
This is because, you have to add the permissions in your code, while login-in the user- not just adding permissions in the App Settings.
For eg, if you are using javascript sdk, it is done using the scope parameter. Reference
You can always test your call here: Graph API Explorer
To answer your first question, you can see the answer here, use the Facebook graph api and search /{user id}/permissions.
Some clerification for the rest. You can't get friends email address as answered here. In order to get the friends profile picture you need to add the field picture (you can specify the size like this picture.width().height().
I reccomend you try to use Facebooks Graph Api Explorer to play with the permissions and the info you request.

facebook c# sdk: deleting a request-id

I am using the latest facebook c# sdk (http://facebooksdk.codeplex.com/). After i have sent an apprequest, i want to delete the request id.
This is how i do it at the moment:
var app = new FacebookClient(appid, appsecret);
app.Delete(requestID);
But i am not sure if its get deleted or not. If i try to see if it still exist using the graph api i get:
{
"error": {
"type": "GraphMethodException",
"message": "Unsupported get request."
}
}
But the user still has the request in his notification area. So my question is> Is the request deleted, or did i miss something? Thanks
var url = "https://graph.facebook.com/{0}?access_token={1}";
fb.Delete((String.Format(url, fullRequestId, fb.AccessToken)));
First parameter is requestId and user id like -> fullRequestId = requestId + "_" + fbUser.id
Second parameter is Accesstoken
I'm just getting started on this myself, but I'm guessing that you need to instantiate the FacebookClient with the authorization code from the user, not with your application data. The way I understand it, the request is sent by the user not your application. Hence the need to use the users authorization code to get information about the requeset.
This is what's working for me (sorry it's VB.Net):
Dim fb As FacebookClient = New FacebookClient(Config.FacebookAppId,Config.FacebookAppSecret)
Dim result = fb.Delete(String.Format("{0}_{1}?access_token={2}", facebookRequestId, facebookUserId, fb.AccessToken))

Categories