很多开发者习惯使用CSOM来新建SPO Site,但是新建Microsoft 365 Group Site时,会发现CSOM根本不支持Microsoft 365 Group Site,Template为Group#0的创建,会遇到如下错误:
Microsoft.SharePoint.Client.ServerException HResult=0x80131500 Message=The web template GROUP#0 is not available for sites on this tenant. Source=Microsoft.SharePoint.Client.Runtime StackTrace: at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream) at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse() at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb) at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
解决方案:这种情况下,我们只能使用Graph API 来新建Group#0的Team Site。
实施步骤:
1. 在AAD中新建Native App
2. 复制App ID,需要添加到后续的code中
3. 授权Graph API Permission:
Groups.ReadWite.All, Directory.ReadWrite.All, openid, Team.Create, User.Read
4. 示例代码:
using System; using System.Net.Http; using System.Net.Http.Headers; using System.Collections.Generic; using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Text; namespace CreateGroupMultiGeo { class Program { static async Task Main(string[] args) { string clientId = "50168119-04dd-0000-0000-000000000000"; string email = "someuser@contoso.onmicrosoft.com"; string passwordStr = "password"; var req = new HttpRequestMessage(HttpMethod.Post, "https://login.microsoftonline.com/bc8dcd4c-0d60-0000-0000-000000000000/oauth2/token") { Content = new FormUrlEncodedContent(new Dictionary{ ["resource"] = "https://graph.microsoft.com", ["grant_type"] = "password", ["client_id"] = clientId, ["username"] = email, ["password"] = passwordStr, ["scope"] = "openid" }) }; HttpClient httpClient = new HttpClient(); var res = await httpClient.SendAsync(req); string json = await res.Content.ReadAsStringAsync(); if (!res.IsSuccessStatusCode) { throw new Exception("Failed to acquire token: " + json); } var result = (JObject)JsonConvert.DeserializeObject(json); //create a group HttpClient httpClientGroup = new HttpClient(); httpClientGroup.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.Value("access_token")); // Create a string variable and get user input from the keyboard and store it in the variable string grpName = "MultiGeoGraphAPIGrp1"; string contentGroup = @"{ 'displayName': '" + grpName + @"'," + @"'groupTypes': ['Unified'], 'mailEnabled': true, 'mailNickname': '" + grpName + @"'," + @"'securityEnabled': false, 'visibility':'Public', 'preferredDataLocation':'GBR', 'owners@odata.bind': ['https://graph.microsoft.com/v1.0/users/ecc0fc81-244b-0000-0000-000000000000'] }"; var httpContentGroup = new StringContent(contentGroup, Encoding.GetEncoding("utf-8"), "application/json"); var responseGroup = httpClientGroup.PostAsync("https://graph.microsoft.com/v1.0/groups", httpContentGroup).Result; var content = await responseGroup.Content.ReadAsStringAsync(); dynamic grp = JsonConvert.DeserializeObject(content); Console.WriteLine(responseGroup.Content.ReadAsStringAsync().Result); System.Threading.Thread.Sleep(3000); //create a Team HttpClient httpClientTeam = new HttpClient(); httpClientTeam.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.Value("access_token")); //create a team string contentTeam = @"{ 'memberSettings': { 'allowCreateUpdateChannels': true }, 'messagingSettings': { 'allowUserEditMessages': true, 'allowUserDeleteMessages': true }, 'funSettings': { 'allowGiphy': true, 'giphyContentRating': 'strict' } }"; var httpContentTeam = new StringContent(contentTeam, Encoding.GetEncoding("utf-8"), "application/json"); ////Refere: https://docs.microsoft.com/en-us/graph/api/team-put-teams?view=graph-rest-1.0&tabs=http var responseTeam = httpClientTeam.PutAsync(@"https://graph.microsoft.com/v1.0/groups/" + grp.id + @"/team", httpContentTeam).Result; Console.WriteLine(responseTeam.Content.ReadAsStringAsync().Result); Console.ReadKey(); } } }
谢谢阅读