使用Microsoft Graph API C# 5.21分配许可证时遇ODataError异常
问题:Microsoft Graph API C# 5.21版本分配许可证时出现ODataError错误
在使用Microsoft Graph API C# 5.21版本为用户分配许可证时,触发了Microsoft.Graph.Models.ODataErrors.ODataError: 'Exception_WasThrown'错误,相关代码如下:
代码片段1:用户创建逻辑
private static async Task<bool> EpostaKontrol(string eposta, GraphServiceClient graphClient) { var users = await graphClient.Users[eposta].GetAsync(); if (users.AccountEnabled == true) { return false; } else { return true; } } private async void ButtonKullanıcıAç_Click(object sender, EventArgs e) { //CSV'yi Hazırla var csv = new StringBuilder(); csv.AppendLine("Kullanıcı Adı,Parola,Mail Adresi,İsim,Telefon"); var dosyaSecildi = false; while (!dosyaSecildi) { if (saveFileDialog1.ShowDialog() == DialogResult.OK) { dosyaSecildi = true; filePath = saveFileDialog1.FileName; } else { MessageBox.Show("Lütfen bir dosya seçiniz."); filePath = string.Empty; } } var options = new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }; var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options); var graphClient = new GraphServiceClient(clientSecretCredential, scopes); //Progressbar'ı hazırla int kullanıcı_sayısı = satır_sayısı; int artis = 100 / kullanıcı_sayısı; progressBar1.Step = artis; progressBar1.Value = 0; progressBar1.Visible = true; int i = 2; int satır = 1; using var reader2 = new StreamReader(file); { while (!reader2.EndOfStream) { if (satır == 1) { reader2.ReadLine(); satır++; continue; } // CSV'yi Okumaya Hazırla string line = reader2.ReadLine(); string[] values = line.Split(','); Console.WriteLine(line[3]); Console.WriteLine(line); try { // Kullanıcıyı Aç string isim = values[3]; string Mail = isim.Trim().Replace(" ", string.Empty).ToLower(); Mail = Tr_to_ASCII(Mail); var userprincipalname = $"{Mail}@onlinedersmerkezi.com"; var user = new User { AccountEnabled = true, DisplayName = isim, MailNickname = Mail, UserPrincipalName = userprincipalname, PasswordProfile = new PasswordProfile { ForceChangePasswordNextSignIn = false, Password = textBox1.Text }, UsageLocation = "TR", AssignedLicenses = new List<AssignedLicense> { new AssignedLicense { SkuId = Guid.Parse("314c4481-f395-4525-be8b-2ec4bb1e9d91"), } } }; Console.WriteLine(user.MailNickname); Console.WriteLine(user.UserPrincipalName); await graphClient.Users.PostAsync(user); Thread.Sleep(2000); // !Kullanıcıyı Aç // CSV Adlı Değişkene Kullanıcıyı Yaz var newLine = string.Format($"{userprincipalname},{textBox1.Text},{values[2]},{values[3]},{values[4]}"); csv.AppendLine(newLine); progressBar1.PerformStep(); Console.WriteLine(reader2.EndOfStream); // !CSV Adlı Değişkene Kullanıcıyı Yaz } catch (Exception) { // Kullanıcıyı Aç // Kullanıcı Adı Kullanılmış Mı Kontrol Et Varsa i'yi Arttır string isim = values[3]; string Mail = isim.Trim().Replace(" ", string.Empty).ToLower(); Mail = Tr_to_ASCII(Mail); var userprincipalname = Mail + "_" + i + "@onlinedersmerkezi.com"; while (await EpostaKontrol(userprincipalname, graphClient)) { userprincipalname = Mail + "_" + i + "@onlinedersmerkezi.com"; i++; } // !Kullanıcı Adı Kullanılmış Mı Kontrol Et Varsa i'yi Arttır var user = new User { AccountEnabled = true, DisplayName = isim, MailNickname = Mail, UserPrincipalName = userprincipalname, PasswordProfile = new PasswordProfile { ForceChangePasswordNextSignIn = false, Password = textBox1.Text }, UsageLocation = "TR" }; Console.WriteLine(user.MailNickname); Console.WriteLine(user.UserPrincipalName); await graphClient.Users.PostAsync(user); Thread.Sleep(2000); // !Kullanıcıyı Aç // CSV Adlı Değişkene Kullanıcıyı Yaz var newLine = string.Format($"{userprincipalname},{textBox1.Text},{values[2]},{values[3]},{values[4]}"); csv.AppendLine(newLine); progressBar1.PerformStep(); // !CSV Adlı Değişkene Kullanıcıyı Yaz } } } // CSV Dosyasını Kaydet File.WriteAllText(path: filePath, contents: csv.ToString()); MessageBox.Show("İşlem tamamlandı"); progressBar1.Visible = false; // !CSV Dosyasını Kaydet }
代码片段2:许可证分配逻辑
private async void ButtonLisans_Click(object sender, EventArgs e) { var options = new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }; var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options); var graphClient = new GraphServiceClient(clientSecretCredential, scopes); int satır = 1; using var reader2 = new StreamReader(file); { while (!reader2.EndOfStream) { if (satır == 1) { reader2.ReadLine(); satır++; continue; } string line = reader2.ReadLine(); string[] values = line.Split(','); Console.WriteLine(line[3]); int artis = (100 / satır_sayısı) + 1; progressBar2.Step = artis; progressBar2.Value = 0; progressBar2.Visible = true; if (satır == 1) { continue; } try { var userQuery = await graphClient.Users[values[0]].GetAsync(); var requestBody = new Microsoft.Graph.Users.Item.AssignLicense.AssignLicensePostRequestBody { AddLicenses = new List<AssignedLicense>{ new AssignedLicense { DisabledPlans = new List<Guid?> { new Guid { }, }, SkuId = Guid.Parse("314c4481-f395-4525-be8b-2ec4bb1e9d91"), }, }, RemoveLicenses = new List<Guid?> { new Guid { }, }, }; await graphClient.Users[userQuery.Id].AssignLicense.PostAsync(requestBody); progressBar2.PerformStep(); } catch (Exception ex) { var msg = MessageBox.Show("Bir hata oluştu. Bu hatanın muhtemel sebebi {values[0]} adında bir kullanıcı olmamasıdır. Eğer hatanın bu olmadığına eminseniz Evet butonuna basın.", "Hata", MessageBoxButtons.YesNo, MessageBoxIcon.Error); if (msg == DialogResult.Yes) { MessageBox.Show($"Bu hata mesajını lütfen info@onlinedersmerkezi.com e-posta adresine e-posta olarak gönderin: {ex.Message}"); } } } Thread.Sleep(10000); MessageBox.Show("İşlem tamamlandı"); progressBar2.Visible = false; } }
解决方案
错误根源在于许可证分配的请求体中,DisabledPlans和RemoveLicenses列表被设置为包含空Guid对象的列表,而Graph API要求如果不需要禁用计划或移除许可证,需将这两个参数设置为空列表。
修正后的请求体代码如下:
var requestBody = new Microsoft.Graph.Users.Item.AssignLicense.AssignLicensePostRequestBody { AddLicenses = new List<AssignedLicense>{ new AssignedLicense { // 如果不需要禁用任何计划,设置为空列表 DisabledPlans = new List<Guid?>(), SkuId = Guid.Parse("314c4481-f395-4525-be8b-2ec4bb1e9d91"), }, }, // 如果不需要移除任何许可证,设置为空列表 RemoveLicenses = new List<Guid?>(), };
此外,还需确保:
- 应用程序已被授予正确的权限(如
User.ReadWrite.All、Directory.ReadWrite.All) - 目标用户已设置
UsageLocation(在用户创建逻辑中已处理) - 使用的SkuId对应租户中可用的许可证
内容的提问来源于stack exchange,提问作者Doruk Han
相关产品推荐
相关产品推荐

