Reputation: 11
I am using below code to get all the users from Active Directory:
static async Task Main(string[] args)
{
int Flag = 0;
// var message = await result;
try
{
var tenantId = "XXXXX.onmicrosoft.com";
string searchCriteria = "";
string searchString = "";
string tokenUrl = $"https://login.microsoftonline.com/XXXXX.onmicrosoft.com/oauth2/v2.0/token";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
//I am Using client_credentials as It is mostly recommended
tokenRequest.Content = new FormUrlEncodedContent(new System.Collections.Generic.Dictionary<string, string>
{
["grant_type"] = "client_credentials",
["client_id"] = "XXX9",
["client_secret"] = "XXXXXX",
["scope"] = "https://graph.microsoft.com/.default"
});
dynamic json;
AccessTokenClass results = new AccessTokenClass();
//New Block For Accessing Data from Microsoft Graph Rest API
HttpClient client = new HttpClient();
var tokenResponse = await client.SendAsync(tokenRequest);
json = await tokenResponse.Content.ReadAsStringAsync();
results = JsonConvert.DeserializeObject<AccessTokenClass>(json);
HttpClient _client = new HttpClient();
string urlGraphUsers = "https://graph.microsoft.com/v1.0/users?$top=999";
// odata_nextlink
do
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format(urlGraphUsers));
//Passing Token For this Request
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
//unable to get department name in response
HttpResponseMessage response = await _client.SendAsync(request);
string responseBody = await response.Content.ReadAsStringAsync();
dynamic objGpraphUserList = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());
var apiResponse = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<jsonModel>(apiResponse);
urlGraphUsers = data.odata_nextLink;
foreach (valueModel r in data.value.ToList())
{
//Print all the fields ,but unable to get Reporting Manager name and Department
Console.WriteLine(r.displayName);
Console.WriteLine(r.mail);
}
if (Flag == 0)
{
await context.PostAsync($"No Search results found! Please Try again");
}
}
while (urlGraphUsers != null);
}
catch
{
await context.PostAsync($"Unknown Exception Occurred. Unable to search results!");
context.Done(true);
}
Console.WriteLine(Flag);
Console.WriteLine("Flag");
context.Done(true);
}
public class jsonModel
{
public string @odata_context { get; set; }
public string @odata_nextLink { get; set; }
public List<valueModel> value { get; set; }
}
public class valueModel
{
public List<string> businessPhones { get; set; }
public string displayName { get; set; }
public string givenName { get; set; }
public string jobTitle { get; set; }
public string mail { get; set; }
public string mobilePhone { get; set; }
public string officeLocation { get; set; }
public string preferredLanguage { get; set; }
public string surname { get; set; }
public string userPrincipalName { get; set; }
public string id { get; set; }
}
I am unable to get Department name in response .Obviously something like r.departmentName doesn't work here.
And i am only getting 100 users ,even though i use odata.nextlink while loop. This do while loop runs only one time and shows only 100 users . Value of data.odata_nextLink; in the first loop itself is null.
How to fetch all the users using pagination and also department name and manager name or directReports. Please help, as i am beginner.
Upvotes: 1
Views: 606
Reputation: 3495
I recommend to leverage Microsoft .NET SDKs to avoid reinventing the wheel. This should work using Microsoft.Graph.Beta nuget package. This due MS Graph V1 not supporting user manager expands.
private static async Task PrintUsersWithManager()
{
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
.WithClientSecret(clientSecret)
.Build();
var token = await app.AcquireTokenForClient(new[] { ".default" }).ExecuteAsync();
var graphServiceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
async (message) =>
{
var result = await app.AcquireTokenForClient(new[] { ".default" }).ExecuteAsync();
message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
}
)
);
var page = await graphServiceClient.Users.Request()
.Expand(u => u.Manager)
.GetAsync();
var users = new List<User>();
users.AddRange(page);
while (page.NextPageRequest != null)
{
page = await page.NextPageRequest
.Expand(u => u.Manager)
.GetAsync();
users.AddRange(page);
}
foreach (var item in users)
{
Console.WriteLine(JsonConvert.SerializeObject(new
{
item.Id,
item.DisplayName,
item.Department,
Manager = item.Manager != null ? new
{
item.Manager.Id,
displayName = ((User)item.Manager).DisplayName
} : null
}));
}
}
Upvotes: 1
Reputation: 15754
As far as I know, the user just has property department
but not departmentName
, you can refer to this document.
In you code, when you do the "deserialize" operation, you need to let it know the odata_nextLink
refers to @odata.nextLink
field in json response. So please modify your code as below:
public class jsonModel
{
[JsonProperty("@odata.context")]
public string odata_context { get; set; }
[JsonProperty("@odata.nextLink")]
public string odata_nextLink { get; set; }
public List<valueModel> value { get; set; }
}
After that, your code will work fine, the data.odata_nextLink
will not be null.
Hope it helps~
Upvotes: 1