我试图通过Microsoft Graph从sharepoint列表中获取项目列表。 这是我用来获取应用程序令牌的方法:
public async Task<string> GetAppToken(string tenantId, string clientId, string clientSecret)
{
var host = "https://login.microsoftonline.com";
var tokenUri = $"/{tenantId}/oauth2/v2.0/token";
var contentType = "application/x-www-form-urlencoded";
var requestedResource = "https%3A%2F%2Fgraph.microsoft.com%2F.default";//&resource=https%3A%2F%2Fgraph.microsoft.com%2F.default
var request = $"grant_type=client_credentials&client_id={clientId}&client_secret={clientSecret}&scope={requestedResource}";
var resultContent = "fail";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(host);
var content = new StringContent(request, Encoding.UTF8, contentType);
var result = await client.PostAsync(tokenUri, content);
resultContent = await result.Content.ReadAsStringAsync();
}
var json = JsonConvert.DeserializeObject<dynamic>(resultContent);
return json.access_token;
}
返回的访问令牌包含以下角色:
"Mail.ReadWrite",
"Device.ReadWrite.All",
"User.ReadWrite.All",
"Domain.ReadWrite.All",
"Calendars.Read",
"Group.Read.All",
"Directory.ReadWrite.All",
"MailboxSettings.Read",
"Contacts.ReadWrite",
"Group.ReadWrite.All",
"Notes.Read.All",
"User.Invite.All",
"Files.ReadWrite.All",
"Directory.Read.All",
"User.Read.All",
"Files.Read.All",
"Mail.Read",
"Calendars.ReadWrite",
"Mail.Send",
"MailboxSettings.ReadWrite",
"Contacts.Read",
"IdentityRiskEvent.Read.All",
"Member.Read.Hidden",
"Reports.Read.All",
"Notes.ReadWrite.All"
这是我用来发出请求的代码:
token = await GetAppToken();
var client = new HttpClient();
var queryString = new NameValueCollection();
client.DefaultRequestHeaders.Authorization
= new AuthenticationHeaderValue("Bearer", token);
var uri = $"https://graph.microsoft.com/beta";
var path = $"/sites/{siteId}/lists/{listId}/items";
var responseString = string.Empty;
try
{
var response = await client.GetAsync($"{uri}{path}");
if (response.Content != null)
{
responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
}
}
catch (Exception ex)
{
Console.Write(ex.ToString());
}
此网址可以产生回复:
> var path =
> "/sites/[sitecol-guid],[site-guid]/lists/[list-guid]/items";
但即使列表中有项目,值集合也是空的。 这是实际的json结果:
{
"@odata.context":"graph.microsoft.com/beta/$metadata#sites('host, site-id')/lists('list-id')/items",
"value":[]
}
我也尝试过这种格式的列表请求:
var path = "https://graph.microsoft.com/beta/sharepoint:/{list-path}"
这产生了一个有效的json响应,详细说明了列表信息,但当我在/ items段上添加时,我收到了这个错误:
&#34;找不到该细分受众群的资源&#39;。&#34;,
我错过了什么?
答案 0 :(得分:2)
这是我花了一段时间才能从文档中弄清楚的事情。
首先,在您将其用于Microsoft Graph Explorer之前,不要以编程方式进行任何操作-这只是浪费时间。
第二,测试版尚未准备好用于您的生产系统,因此,尽管运行良好,但不要依赖它,而应使用REST API v1.0。
如果您知道站点和列表的ID,则所有URL都将以以下其中之一开头:
https://graph.microsoft.com/v1.0/sites/{siteId}/lists/{listId}/
https://graph.microsoft.com/beta/sites/{siteId}/lists/{listId}/
注意: 在下面的示例中,我给出了通用URL,然后给出了一个对我有用的真实世界-因此您可以看到格式是什么看起来像。
如果您不知道listId
,可以说我们正在查看根站点中的列表,则可以通过在Microsoft Graph Explorer中使用此URL来获取它们,然后单击 Run查询:
https://graph.microsoft.com/v1.0/sites/{siteId}/lists
https://graph.microsoft.com/v1.0/sites/root/lists
如果要获取列表中的所有列,请将此URL粘贴到Microsoft Graph Explorer中,然后单击运行查询
https://graph.microsoft.com/v1.0/sites/{siteId}/lists/{listId}/columns
https://graph.microsoft.com/v1.0/sites/root/lists/ff34268a-d9ff-49c0-99a9-75c6b2eee62e/columns
这将返回类似于:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('root')/lists('ff34268a-d9ff-49c0-99a9-75c6b2eee62e')/columns",
"value": [
{
"columnGroup": "Custom Columns",
"description": "",
"displayName": "Title",
"enforceUniqueValues": false,
"hidden": false,
"id": "fa564e0f-0c70-4ab9-b863-0177e6ddd247",
"indexed": false,
"name": "Title",
"readOnly": false,
"required": true,
"text": {
"allowMultipleLines": false,
"appendChangesToExistingText": false,
"linesForEditing": 0,
"maxLength": 255
}
},
...
]
}
要获取列表中内容的值,请使用以下方法:
https://graph.microsoft.com/v1.0/sites/{siteId}/lists/{listId}/items?expand=fields
https://graph.microsoft.com/v1.0/sites/root/lists/ff34268a-d9ff-49c0-99a9-75c6b2eee62e/items?expand=fields
请注意expand=fields
查询实际上将列表中各项的值相加
这将返回类似于:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('root')/lists('ff34268a-d9ff-49c0-99a9-75c6b2eee62e')/items",
"value": [
{
"@odata.etag": "\"6a84a626-dae9-40eb-9c6d-899c6a05ffa8,3\"",
"createdDateTime": "2017-01-03T11:11:42Z",
"eTag": "\"6a84a626-dae9-40eb-9c6d-899c6a05ffa8,3\"",
"id": "1",
"lastModifiedDateTime": "2017-01-10T18:24:58Z",
"webUrl": "https://myexample.sharepoint.com/Lists/Some%20Contacts/1_.000",
"createdBy": {
"user": {
...
}
},
"lastModifiedBy": {
"user": {
...
}
},
"parentReference": {},
"contentType": {
"id": "0x010062202D579C40994CA18FDBA6760B9545"
},
"fields@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('root')/lists('ff34268a-d9ff-49c0-99a9-75c6b2eee62e')/items('1')/fields/$entity",
"fields": {
"@odata.etag": "\"6a84a626-dae9-40eb-9c6d-899c6a05ffa8,3\"",
"Title": "Dr",
"First_x0020_Name": "David",
"Surname": "Simpson",
"Location": "Nottingham",
"First_x0020_Created": "2017-01-03T08:00:00Z",
"Age@odata.type": "#Single",
"Age": 25,
"id": "1",
"ContentType": "Item",
"Modified": "2017-01-10T18:24:58Z",
"Created": "2017-01-03T11:11:42Z",
"AuthorLookupId": "11",
"EditorLookupId": "11",
"_UIVersionString": "1.0",
"Attachments": false,
"Edit": "",
"LinkTitleNoMenu": "Dr",
"LinkTitle": "Dr",
"ItemChildCount": "0",
"FolderChildCount": "0",
"_ComplianceFlags": "",
"_ComplianceTag": "",
"_ComplianceTagWrittenTime": "",
"_ComplianceTagUserId": ""
}
},
...
]
}
尽管我使用的是图表的v1.0,但beta的工作原理相同。
在我的实际应用中,我使用offline_access Sites.ReadWrite.All
作为OAuth舞蹈的范围。前者允许令牌刷新。后者用于访问Microsoft Graph中的SharePoint Online。
您的授权URL应该如下所示:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?client_id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX
&response_type=code
&redirect_uri=https%3A%2F%example.ngrok.io%2Foauth2%2Fcallback
&response_mode=query
&scope=offline_access+openid+Sites.ReadWrite.All
&prompt=consent
旁白::确保您使用的是Microsoft Graph API(在https://graph.microsoft.com/),而不是Azure AD Graph API(在https://graph.windows.net/)。如果您在OAuth舞蹈中放错了示波器,请bad things will happen。
关于使用Microsoft Graph API的一件好事是,您不必事先在Azure门户中添加任何权限,因为您只需将权限添加到OAuth范围并重新进行身份验证即可。这要容易得多。
答案 1 :(得分:-1)
确保您已获得管理员同意。这是一个例子。
https://login.microsoftonline.com/ {房客ID} / adminconsent?client_id = {client id}&state = 12345&redirect_uri = http://localhost
答案 2 :(得分:-1)
如评论中所述,您错过了Grant Permissions
的重要步骤,该步骤基本上是管理员同意的步骤。
仅应用程序权限(始终需要管理员同意)需要此许可。如果应用程序具有委派的权限,那么通过Grant permissions
,您可以代表所有用户有效地表示同意,一旦完成,它将禁止用户出现提示>
如本博客所述(免责声明我自己的博客)-Consume the Graph API and create O365 groups/modern team sites with CSOM C#中所述,一旦我们已授予并保存了应用程序所需的权限,便需要Grant permissions
。