I tried to do the Learning Path on Microsoft. But at Build apps with Microsoft Graph – Associate under Access User Data from Microsoft Graph in Unit 4 of 8 I've get an "Ressource not found" Error. If I try to catch my profile picture in the graph explorer I get an Ressource not found Error too, but under "Beta" it displays my picture. I think this Learn Path is outdated.
My Question is, how can I change the code given in the Learning Path to speaks to the BETA and not v1.0.
var resultsUserPhoto = requestUserPhoto.GetAsync().Result;
This line makes the problem.
Greetings.
I have understood that you are using the Microsoft Graph V1.0 SDK. To hit the beta endpoint for only 1 request you can modify the BaseUrl to graph client and make a beta request.
graphClient.BaseUrl = "https://graph.microsoft.com/beta";
var pictureStream = await graphClient.Me.Photo.Content.Request().GetAsync();
For further referrence see this SO Thread.
This code works for me with both v1.0 and beta but only if I really have profile photo:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var stream = await graphClient.Me.Photo.Content
.Request()
.GetAsync();
For profile without photo it returns Resource not found.
Related
I try to retrieve the site url when a microsoft-365 group is created in sharepoint using graph sdk. I read from docs that in order to access a group team site I should use GET /groups/{group-id}/sites/root BUT I don't know how to do it.
Also I have tried code below but throws exception that resource was not found.
var site = await graphClient.Sites[$"/groups/{group.Id}/sites/root"]
.Request()
.GetAsync();
I would like to know if I can modify the code above and use the group id to retrieve the active site url.
Thanks in advance.
Try this:
graphClient.Groups["0745be26-2d8a-4f8d-be2d-37356a4794a3"].Sites["root"].Request().GetAsync().Result;
My test result:
I have Azure Function v3 and I want to update Sharepoint user profile properties with CSOM and .NET standard 2.0 by using global admin account credentials. Reading is working.
var site = new Uri("https://domain-admin.sharepoint.com");
using (var authenticationManager = new AuthenticationManager())
using (var context = authenticationManager.GetContext(site, user, password))
{
var peopleManager = new PeopleManager(context);
var personProperties = peopleManager.GetPropertiesFor(accountName);
context.Load(personProperties, p => p.AccountName, p => p.UserProfileProperties);
await context.ExecuteQueryAsync();
Console.WriteLine(personProperties.UserProfileProperties["FirstName"]); //works
peopleManager.SetSingleValueProfileProperty(personProperties.AccountName, "FirstName", "CSOMvalue");
await context.ExecuteQueryAsync(); //error, access denied
}
Exact Error message: System.Private.CoreLib: Exception while executing function: FunctionName. Microsoft.SharePoint.Client.Runtime: Access denied. You do not have permission to perform this action or access this resource.
AuthenticationManager class is taken from MS docs from here
Im using Microsoft.SharePointOnline.CSOM v16.1.20518.12000 nuget package.
I made .NET Framework 4.7.2 web app and it worked using SharePointOnlineCredentials. But I want to know how to get it working on .NET Standard 2.0.
From my past experience and couple of hours research :
When you use Azure AD Application, you can read through the User Profiles - but not perform CSOM write operation.
reference :
Though the article says it is applicable for using app-only, this behavior has been observed Azure AD Application in general (user + app as well) - hence the reason why you are able to read but however not write.
As mentioned in the article you will have to the Sharepoint App only context and perform a read/write operation.
context = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, "[Your Client ID]", "[Your Client Secret]")
Here the authenticationmanager is of the SharepointPNPcoreOnline library.
This article details the same.
If you want the user context while performing the same (not usually required because you re performing at the UPA ) - you can create the app accordingly - but really not sure whether the SharepointPNPCOreOnline supports this.
I'm implementing an internal procedure to generate invoices from my database. In using .NET Core. I installed the Xero.Api.SDK.Core v. 1.1.4
I find the Xero documentation quite difficult to understand and a bit up to date. I took a look to the Github repository and they refer only to OAuth 2.0. In my case I don't want any user interaction because I want a background process.
I created an account as developer and a demo company for test.
I googled a bit and I found in a site an example how to connect to the api (I couldn't find any details in the Xero documentation).
X509Certificate2 cert = new X509Certificate2(#"public_privatekey.pfx", "password");
var api = new Xero.Api.Example.Applications.Private.PrivateAuthenticator(cert);
var private_app_api = new XeroCoreApi("https://api.xero.com",
new PrivateAuthenticator(cert),
new Consumer("ClientId", "ClientSecret"),
null, null);
Now, I thought, I should use the api. I tried to read the list of contacts:
var contacts = private_app_api.Contacts;
var list = contacts.FindAsync().Result;
The result is the following error:
System.AggregateException: 'One or more errors occurred. (oauth_problem=consumer_key_unknown&oauth_problem_advice=Consumer%20key%20was%20not%20recognised)'
Inner Exception
UnauthorizedException: oauth_problem=consumer_key_unknown&oauth_problem_advice=Consumer%20key%20was%20not%20recognised
Then, I downloaded the repository from Github. I copy and paste the ClientId and ClientSecret and run the tests. No one test is passed!
My goal is to create a contact or find one in the list, create an invoice and save the invoice in PDF format in my storage.
How can I do that? Is there any example for that?
PS: In the developer forum the login doesn't work and the Postman collection is old and it doesn't either.
Update
I was desperate. I tried to connect to the apis in another way with XOauth. Worst. I created the connection as Xero explains on Github.
When I try to connect with
xoauth connect
a new tab in my browser is opened and...
Postman Update
I followed the steps with Postman. I opened the collection in my Postman. In the environment I updated client_id and client_secret from the Xero Developer site and then the following configurations:
re_directURI: https://developer.xero.com
scopes: offline_access profile email accounting.transactions
Auth URL: https://login.xero.com/identity/connect/authorize
Access Token: https://identity.xero.com/connect/token
I opened Get started api, Generate token and I gave the same result.
Honestly, it was quite a mess. I spent more than 2 weeks to understand how to call Xero. I created a post to explain step by step what I have to do.
There were a lot of issues:
understand the Xero documentation because it is not very clear
find the right values to put in the request
translate the Postman request in code
no Xero documentation for that, only a useless bunch of projects
It is quite long to explain everything but for example if you want to read an Organization the code with RestSharp is:
/// <summary>
/// Gets the organizations.
/// </summary>
/// <returns>OrganizationResponse.</returns>
public OrganizationResponse GetOrganizations()
{
var _client = new RestClient("https://api.xero.com/connections");
_client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + _settings.AccessToken);
var response = _client.Execute<IList<Organization>>(request);
return response;
}
I'll create other posts to explain how to implement more functions.
I created a NuGet package for that. Source code on Github.
My C# program uses the Microsoft.Graph Nuget. And it needs be able to ensure that it has the correct Microsoft Graph application permissions.
I know how to add permissions in AD, but I want my program to be able test it has the permissions it needs.
Example of what I want to achieve :
var graphClient = new GraphServiceClient(authenticationProvider);
if(!graphClient.GetPermissions().Contains("AdministrativeUnit.Read.All"))
{
throw new Exception("Missing Permission AdministrativeUnit.Read.All")
}
Thanks in advance !
It's a long way.
Here I provide a general idea of Microsoft Graph beta version(through HTTP method):
Get the Object ID of the servicePrincipal based on the App ID: GET
https://graph.microsoft.com/beta/servicePrincipals?$filter=appId eq
'{App ID}'.
Get the appRole information (the application permission information)
based on the Object ID from step 1: GET
https://graph.microsoft.com/beta/servicePrincipals/{Object ID}/appRoleAssignedTo.
Get a match list of appRoleID and Microsoft Graph application permission name: GET
https://graph.microsoft.com/beta/servicePrincipals?$filter=appId eq
'00000003-0000-0000-c000-000000000000'. Please note that
"00000003-0000-0000-c000-000000000000" is a fixed value, which
represents the App ID of the Microsoft internal Graph App.
Compare the results of the 2nd and 3rd steps and you will know which
application permissions are in your Azure AD app.
By the way, Get appRoleAssignment is only available in beta version currently, but beta version api is not recommended to use.
APIs under the /beta version in Microsoft Graph are subject to change.
Use of these APIs in production applications is not supported.
I'm trying to use the Graph SDK to get a specific Sharepoint site by URL so I can read and write the list, create document libraries, and add documents to existing libraries.
This works to get the root:
var site = await graphClient.Sites[SPUrl].Request().GetAsync();
This doesn't work to get the site I want:
var site = await graphClient.Sites[SPUrl+"/segment1/segment2/site"].Request().GetAsync();
And this doesn't work to get the site by URL -- it tells me "the provided path does not exist or does not represent a site":
var siteByPath = await graphClient.Sites[SPUrl].SiteWithPath("/segment1/segement2/site").Request().GetAsync();
But using the Graph Explorer, this works:
https://graph.microsoft.com/v1.0/sites/my.site.com:/sites/segment1/segment2/site?$select=id
Using the Graph Explorer I determined that each segment of the URL is considered its own site, but didn't have any luck doing this -- the error is "provided identifier is malformed - id is not valid":
var site = await graphClient.Sites[SPUrl].Sites["segment1"].Request().GetAsync();
What am I missing?
With the Sharepoint CSOM you could just ask for a site by its URL. My application is in Azure now and being authenticated by through OAuth tokens, not by a username and password handled within the application, so I'm not sure I can pass that authentication through CSOM. As far as I can tell I need to use Graph now.
It would appear that the problem was that if you're going to query the sites under a site root, you need to add the ":" to your original root site string. So
"await graphClient.Sites[SPUrl].Sites["/segment1/segment2/site"].Request().GetAsync();" needs to be
"await graphClient.Sites[SPUrl+":"].Sites["/segment1/segment2/site"].Request().GetAsync();" which would make it match the syntax used in the Graph Explorer.
I had assumed that asking for a Site using the SDK would handle that, but I was wrong.