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.
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 am running asp.net application on Facebook,which has multiple pages.
On landing page I obtain access token.
Question is how to persist that access token so that I can use it in other pages
to access current user data.
Current when I try following in other pages,
Facebook.FacebookAPI fbApi = new Facebook.FacebookAPI();
JSONObject currentUser = fbApi.Get("/me");
it breaks saying unauthorized.
You should just store the access token in your database along with a user ID reference. Alternatively you can just use a client side SDK like the Facebook Javascript SDK which will persist for you without having to go extra effort.
I don't think you're using the most recent version of the API. It looks like you're using the deprecated one from https://github.com/facebook/csharp-sdk#readme
If you're using the latest one, then you can persist the access token. Grab the latest from:
https://github.com/facebook-csharp-sdk/facebook-csharp-sdk/#readme
I've got credentials of an account with access to Google Analytics,
I'm looking to utilise the Analytics Core Reporting API http://code.google.com/apis/analytics/docs/gdata/home.html
I've found examples which use username/password calling setUserCredentials, but have seen comments this is less secure/has a low request limit (And doesn't exist in the lastest client).
Plus I've seem examples which use oauth, but require user interaction and grant access to the users google account.
However I'm looking to run a service which doesn't require any user interaction, and connects to a predefined google account (un-related to the user viewing it).
I can then store the results in a database, and end users can query the results from the database.
I've seen information about using AccessType = Offline when you first login, which then returns an access token and a refreshtoken.
http://code.google.com/apis/accounts/docs/OAuth2WebServer.html#offline
In my example though, the end user will never login to the application.
Could I have a seperate admin application which gets a refresh token, and stores the refresh token in the config/lookup table?
Then the main application can use the refresh token pulling from the config/lookup table, and get an access token to be able to query the Google Analytics account.
I'm looking for a C# example which uses AccessType = Offline, and seperates out the fetching of the refresh token and using the refresh token to get an access token to query the google analytics account.
Create your app https://code.google.com/apis/console/
For you App, turn on access to Google Analytics, and create an OAuth 2.0 client ID for your website.
Browse to:
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=YOUR_APP_ID.apps.googleusercontent.com&access_type=offline&scope=https://www.googleapis.com/auth/analytics.readonly&redirect_uri=HTTP://YOUR_CALL_BACK_URL
Having changed YOUR_APP_ID, YOUR_CALL_BACK_URL to the relevant values.
Important to include access_type=offline.
Press Grant Access, this will redirect to HTTP://YOUR_CALL_BACK_URL?code=THIS_IS_YOUR_CODE. Copy the code in the URL.
With the code, request the Refresh Token using CMD prompt.
curl -d "code=THIS_IS_YOUR_CODE&client_id=YOUR_APP_ID.apps.googleusercontent.com&client_secret=YOUR_APPS_SECRET_CODE&redirect_uri=HTTP://YOUR_CALL_BACK_URL&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token
Having changed THIS_IS_YOUR_CODE, YOUR_APP_ID, YOUR_APPS_SECRET_CODE, YOUR_CALL_BACK_URL to the relevant values.
Record the refresh_token returned.
Download the latest version of the Core Reporting V3.0 .net libraries
http://code.google.com/p/google-api-dotnet-client/wiki/Downloads
There is a bug in the current version of Google.Apis.Analytics.v3.cs, to fix this copy the code in this file to your local solution (And don’t reference Google.Apis.Analytics.v3.bin)
http://code.google.com/p/google-api-dotnet-client/source/browse/Services/Google.Apis.Analytics.v3.cs?repo=samples&name=20111123-1.1.4344-beta
And change the property Dimensions from a List<system.string> to a string.
Or you'll get an error like me and this guy did http://www.evolutiadesign.co.uk/blog/using-the-google-analytics-api-with-c-shar/
You can then use your Refresh Token, to generate you an Access Token without user interaction, and use the Access Token to run a report against Google Analytics.
using System;
using DotNetOpenAuth.OAuth2;
using Google.Apis.Authentication.OAuth2;
using AnalyticsService = Google.Apis.Analytics.v3.AnalyticsService;
class Program
{
public static void Main()
{
var client = new WebServerClient(GoogleAuthenticationServer.Description, "YOUR_APP_ID.apps.googleusercontent.com", "YOUR_APPS_SECRET_CODE");
var auth = new OAuth2Authenticator<WebServerClient>(client, Authenticate);
var asv = new AnalyticsService(auth);
var request = asv.Report.Get("2012-02-20", "2012-01-01", "ga:visitors", "ga:YOUR_GOOGLE_ANALYTICS_ACCOUNT_ID");
request.Dimensions = "ga:pagePath";
request.Sort = "-ga:visitors";
request.MaxResults = 5;
var report = request.Fetch();
Console.ReadLine();
}
private static IAuthorizationState Authenticate(WebServerClient client)
{
IAuthorizationState state = new AuthorizationState(new string[]{}) { RefreshToken = "REFRESH_TOKEN" };
client.RefreshToken(state);
return state;
}
}
Great Answer Ian and it helped me to get going in the correct Direction more than any other answer I could find online. Something must have changed in the AnalyticsService object because the line:
var request = asv.Report.Get("2012-02-20", "2012-01-01", "ga:visitors", "ga:YOUR_GOOGLE_ANALYTICS_ACCOUNT_ID");
did not work for me and I had to use the following:
var request = asv.Data.Ga.Get("ga:YOUR_GOOGLE_ANALYTICS_ACCOUNT_ID", "2012-01-01", "2012-02-20", "ga:visitors");
Hopefully this will help others like your answer helped me. Thanks!
Ian's answer helped me a lot but I kept getting an error running the curl command. Did some research and found that the steps to get the access code and refresh token can be made easier by going to https://code.google.com/oauthplayground/ and checking your oAuth configuration settings. Top right of the page there is a settings button. selected "Use your own OAuth credentials". You can get your access code and request a refresh token all from here.
Hope this helps.
You can manually get a refresh token from the OAuth Playground.
If you are needing a refresh token for a Service Account as I was, make sure you
Click on the settings on the right.
Check Use your own OAuth credentials
Fill in your Client ID and Secret
Close the settings
Click the Refresh button on step 2
Then save the refresh token for use in your app
I'm trying to create web page that access the (business) private calendar of the company and insert events if the time slot is available. Still I'm facing an authentication problem.
The API manual states that I should use an API key and Oauth2LeggedAuthenticator, so I did all this and the request that is fired is quite okey (it has a oauth token and such) But still the response is an exception with Invalid Credentials; Easy to say is that my credentials are wrong, still clientID, clientSecret and API Key are valid; I doubt the 2 last params of the 2legged authenticater, is this correct?
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);
provider.ClientIdentifier = ClientCredentials.ClientID;
provider.ClientSecret = ClientCredentials.ClientSecret;
var authenticator =
new OAuth2LeggedAuthenticator(ClientCredentials.ClientID, ClientCredentials.ClientSecret, "myworkusername", "workdomain.com");
Google.Apis.Calendar.v3.CalendarService service = new Google.Apis.Calendar.v3.CalendarService(authenticator);
service.Key = ClientCredentials.ApiKey;
var result = service.CalendarList.List().Fetch();
Assert.IsTrue(result.Items.Count > 0);
NB: At the time of writing you can only used 2-legged authentication with Google Apps for Business/Eduction, this won't work on personal accounts as there's no way to get an OAuth 1.0 key/secret pair, you will have to use online authentication at least once (but you can use the out-of-browser option so you don't have to create a dedicated page).
Your code is correct apart from you don't need the first three lines relating to the NativeApplicationClient. This is most likely failing because you haven't properly set the OAuth keys, this causes 401s.
The other thing that causes 401s is using "matt#example.com" instead of "matt" as the username, the username is without including your domain.
To setup OAuth follow the instructions in this article from Google.
The most important parts to note are "Allow access to all APIs" must be unchecked and you have to individually grant access to all the APIs. If this hasn't been done you will get a 401 Invalid Credentials error. You then also need to turn those services on in the api console. If the api console step hasn't been done you will get a different error of 403 Daily Limit Exceeded.
This will cause you problems if you were previously relying on the "Allow access to all APIs" to use various services, you will have to grant them all individually as far as I understand it to use the v3 APIs. This seems to have been confirmed by google (4th reply by Nicolas Garnier) and is supposedly a bug, but that is an old post so it looks as if it's here to stay.
For reference once this has been done, this code will work, which in essence is the same as yours:
var auth = new OAuth2LeggedAuthenticator(domainName, consumerSecret, usernameWithoutDomain, domainName); //domainName is presently used as the OAuth ConsumerKey for Google's 2legged OAuth
var service = new CalendarService(auth);
service.Key = serviceKey;
var results = service.CalendarList.List().Fetch();
Console.WriteLine(results.Items.Count);
So in summary:
In Google Apps "Manage this Domain" > "Advanced Tools"
Using "Manage OAuth domain key" enable key, generate secret, uncheck "Allow access to all APIs".
Using "Manage third party OAuth Client access" enable the APIs you want access to using your domain as "Client Name" and the APIs you want to access e.g. "http://www.google.com/calendar/feeds/" for the calendar.
Then finally create a project in the API console, use the APIKey as the serviceKey in the above example and turn on the APIs you need to access.
I am answering this as I kept hitting this question when I was trying to find out why my code was constantly returning 401s. Hope this helps someone as the Google instructions are awful and scattered all over the place at the moment.
I am having trouble doing something simple like the following
using (SPSite site = new SPSite(topLevelSite))
{
SPWeb rootWeb = site.OpenWeb();
SPWeb newWeb = rootWeb.Webs.Add(siteName, "abc", "abc",1033,template,false,false);
}
But the catch I am trying to add a site to a PKI enabled sharepoint site:
This code works fine when I am dealing with my non pki sharepoint server, but I get the error:
"
The Web Application at https://server/sites/newSite could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system admin may need to add a new request URL mapping to the intended application.
"
My main question is: How do you go about accessing with C# a sharepoint site that is PKI enabled? Do I need to insert my certs somewhere programmatically or what?
Are there steps before I open SPSite, or are there other Objects I need to use that are more PKI friendly?
I would first make sure that the URL you use is the same URL SharePoint itself knows about. This thing is called Alternate Access Mapping and is accessible through the Central Administration. Sometimes people would map the web application to a different URL using DNS and IIS configuration only, without updating SharePoint itself. It might appear to be working correctly when browsing the site, but this kind of error would appear when using the API