How to get the maximum number of members based on users from Azure AD using Graph Api - azure-active-directory

I am getting the the groups based on users from Microsoft Graph Api. Although I am getting the groups but they are coming to total count of 100.
I tried to use paging technique but it is keep failing. Can someone help me out?
var page = graphClient
.Users[uniqueIdentification]
.MemberOf
.Request()
.GetAsync().Result;
var names = new List<string>();
names.AddRange(page
.OfType<Group>()
.Select(x => x.DisplayName)
.Where(name => !string.IsNullOrEmpty(name)));
The above code only return top 100.
When I tried below code for paging it got cast error .
Error:
Unable to cast object of type 'System.Collections.Generic.List`1[Microsoft.Graph.DirectoryObject]' to type 'System.Collections.Generic.IEnumerable`1[Microsoft.Graph.Group]'.
Code:
var group2 = new List<Group>();
var groupsPage = graphClient.Users[uniqueIdentification].MemberOf.Request().Top(300).GetAsync().Result;
group2.AddRange((IEnumerable<Group>)groupsPage.CurrentPage);
while (groupsPage.NextPageRequest != null)
{
groupsPage = groupsPage.NextPageRequest.GetAsync().Result;
group2.AddRange((IEnumerable<Group>)groupsPage.CurrentPage);
}

The maximum sizes of pages are 100 and 999 user objects respectively
and are default .
Some queries are supported only when you use the
ConsistencyLevel header set to eventual and $count to true
For the error:
Unable to cast object of type 'System.Collections.Generic.List`1[Microsoft.Graph.DirectoryObject]' to type 'System.Collections.Generic.IEnumerable`1[Microsoft.Graph.Group]'.
It looks like here group2 is of type list but trying to add/append the page of type Ienumerable to it which is leading to cast error.(note:list implements Ienumerable (parent) but ienumerable doesn't inherit from list as Ienumerable can be list, queue ,stack )
using System.Linq;
While using var group2 = new List<Group>();
try to add .ToList(); or .Cast<group>().ToList(); depending on latest or old type of versions before adding or appending to the group2 of type list
Please check the References to know further details :
List users - Microsoft Graph v1.0 | Microsoft Docs
How to append enumerable collection to an existing list in C# -
Stack Overflow

Related

The collection property 'identifierUris' cannot be used in a 'where' query expression

Using Microsoft.Azure.ActiveDirectory.GraphClient.ActiveDirectoryClient api I am trying to find an existing Application in AAD which has the same as my desired IdentifierUrl. This is so i can decide on creating one or leaving the existing one alone.
I'm using the following calls. However I get this error:
The collection property 'identifierUris' cannot be used in a 'where' query expression. Collection properties are only supported as the source of 'any' or 'all' methods in a 'where' query option
What is the recommended way of doing this? thanks
public static async Task<IApplication> FindApplicationByUrlAsync(string accessToken, string tenantId, string identifierUrl)
{
var graphClient = NewActiveDirectoryClient(accessToken, tenantId);
var matches = await graphClient.Applications.Where(app => app.IdentifierUris.Contains(identifierUrl)).ExecuteAsync();
return matches.CurrentPage.ToList().FirstOrDefault();
}
Use the Any function:
var result = await client.Applications.Where(a => a.IdentifierUris.Any(i => i == identifierUri)).ExecuteAsync();
That'll get translated into a request as follows:
https://graph.microsoft.com/beta/applications?$filter=identifierUris/any(c:c eq 'yourIdentifierUri')
More info on filters for the Azure AD Graph here:
https://msdn.microsoft.com/en-us/library/azure/ad/graph/howto/azure-ad-graph-api-supported-queries-filters-and-paging-options

How to apply a condition to a specific table in every request on Entity Framework?

I have a many-to-many structure mapped to entity framework. This is a sample of what it looks like:
User UserTag Tag
------- -------- -------
IdUser(PK) IdUserTag(PK) IdTag(PK)
Name IdUser(FK) TagName
Desc IdTag(FK) Active
Now, I needed to exclude from any request of any method the viewing of Tags that were Active=false.
First, I tried doing it manually in every method, like:
public User GetById(int id)
{
var item = UserRepository.GetById(id); //This is just a repository that calls the EF context
//EF automatically maps it to the *UserTags* property
foreach(var tag in item.UserTags)
{
if(tag.Tag.Active == false)
item.UserTags.Remove(tag);
}
}
But it throws the following exception:
The relationship could not be changed because one or more of the foreign-key properties is non-nullable
So, I wanted to know if there's a way to conditionaly filter every request made to a specific table, whether it is select or a join request.
Try this in your GetById method:
var user.UserTags = dbContext.Entry(user)
.Collection(u => u.UserTags)
.Query()
.Where(ut => ut.Active == true)
.ToList();
The supplied code fails because it is attempting to remove items from the data entities not the list. If you want to pass the data entity around instead of the data model, you need to not use Remove. Something like the below (untested should work).
tags = item.UserTags.Where((ut) => ut.Active).ToList();
This line will get you a list of data entities that are active. However, you should really map all of this into a data model (see AutoMapper) and then you would not be removing items from the database.

Search For All Locations In Active Dirrectory Via LDAP

I'm working in PL/SQL and searching LDAP ( with A.D defining the schema) for all locations. Right now I can apply a simple search and find all users. Each user has the address information via the following properties:
'physicalDeliveryOfficeName';
'streetAddress';
'l';--city
'st';--state
'postalCode';--zip code
However, I would like to search for all the locations separate from the search done for people. Is it possible to search Active directory to just find the locations(with out looking up each person) ? If so what would the search filter look like ? I tried objectClass=Physical-Location,DC=example,DC=com and didn't find any locations (beyond the schema) . I'm not sure if that's because there's a security issue, or its not possible to look up locations in that way.
What you have listed are attributes in AD. You can return attributes in searches and search for specific values but you'll always return the objects the attributes are attached to (in this case users). You're a little light on the details of how you're searching so I'll take a stab.
You can load just the location attributes you're looking for, be it State, City, etc.
var domain = "mydomain.com";
var dn = "CN=Users,DC=mydomain,DC=com";
var ldapSearchFilter = "(objectClass=user)";
var connection = new LdapConnection(domain);
var attributeList = new string[] { "physicalDeliveryOfficeName", "l", "st"};
try
{
var searchRequest =
new SearchRequest(dn, ldapSearchFilter,
SearchScope.OneLevel,
attributeList);
var searchResponse =
(SearchResponse)connection.SendRequest(searchRequest);
var locationList = (from SearchResultEntry entry in searchResponse.Entries
select entry.Attributes["physicalDeliveryOfficeName"][0].ToString())
.Distinct().ToList();
catch (Exception ex)
{
//Handle errors
}
One thing to keep in mind with this example. If the attributes aren't populated in AD, the WriteLine will throw an error when trying to read the attribute. If you are using some other search type (DirectorySearcher maybe) you should still be able to load just the attributes you want to get back.

Knockoutjs how to data-bind observable array members based on IDs

I'm not if the title explains what I need to achieve or not but I can change it later if some has a better suggestion.
I'm using KO to manage a whole bunch of data on the client side.
Here's the basic.
I have a list of training sessions
Each has a list of training session parts
Each training session parts are referencing items kept in other lists. For example, I have a list of activities (ex: biking, running, swimming, etc.)
Each activity is identified by an ID which is used in the training session parts to identify which activity was used for a particular session.
Now, all these list are stored as observable arrays, and each member of the lists are observables (I use KO.Mapping to map the JSON coming from the server)
When I display a training session in my UI, I want to display various information coming from various lists
Duration: 1h30
Activity: Biking
Process: Intervals
The only information I have in order to link the training session to its component is an ID which is fine. What I'm not sure is how to data-bind the name (text) of my activity to a <p> or <div> so that the name will change if I edit the activity (by using some functionality of the application).
The training session only has the ID to identify the activity, so I don’t know how to bind the name of the activity based on its ID.
Hopefully this makes senses and someone can help me figure it out. I found lots of info on how to bind to observable array but nothing addressing ID and linked information.
The easiest way would probably be to make your own constructors and link the data by hand. You can use mapping if you really want to, but you'll basically have to do the same manual linking, only in a more verbose format.
This is the fiddle with the example implementation: http://jsfiddle.net/aKpS9/3/
The most important part of the code is the linking, you have to take care to create the activity objects only once, and use the same objects everywhere, as opposed to creating new activity objects for the parts.
var TrainingSession = function(rawData, actualActivities){
var self = this;
self.name = ko.observable(rawData.name);
self.parts = ko.observableArray(ko.utils.arrayMap(rawData.parts, function(rawPart){
return ko.utils.arrayFirst(actualActivities(), function(ac){
return ac.ID() == rawPart.ID;
})
}));
}
var Activity = function(rawData){
var self = this;
self.ID = ko.observable(rawData.ID);
self.name = ko.observable(rawData.name);
}
var MainVM = function(rawData){
var self = this;
//first create an array of all activities
self.activities = ko.observableArray(ko.utils.arrayMap(rawData.activities, function(rawAc){
return new Activity(rawAc);
}));
self.trainingSessions = ko.observableArray(ko.utils.arrayMap(rawData.trainingSessions, function(session){
return new TrainingSession(session, self.activities);
}));
}

MVC 3 LINQ Custom Sorting and Filtering with User-Specified Fields (Properties)

I'm writing a custom web app (an administrative utility) that queries a SQL Server database table, and I am giving users the ability to apply their own (limited) custom sorts and filters on the returned information. The sending page allows them to choose up to 3 sort criteria (e.g. Sort 1 then Sort 2 then Sort 3) using drop-down lists on an HTML form. They must also indicate a single letter of the alphabet (through the URL), and the application must return a list of data where field "Sort1" starts with the letter (the filtering is ALWAYS by the Sort1 field).
So for example, they could choose to return a list of all customers whose City starts with the letter "R", sorted by City then State then Name. Or, they could return all customers whose Name starts with "F", sorted by Name then Address then Customer ID.
I totally understand how to do this with fixed (known) fields/properties;
var _data = _data.Where(d => d.Name.StartsWith(letter)).OrderBy(p => p.Name).ThenBy(p => p.Address).ThenBy(p => p.CustomerID);
etc. But in my case, the table properties (fields) to be sorted/filtered are not explicitly known; they are only available to my app as strings. What I'd like to be able to do is...
var _data = _data.Where(d => d.["Sort1"].StartsWith(letter)).OrderBy(p => p.["Sort1"]).ThenBy(p => p.["Sort2"]).ThenBy(p => p.["Sort3"]);
where Sort1, Sort2 and Sort3 are posted form field values, but I know this doesn't work. How can I implement this? I'm using ASP.Net MVC 3 in C#, with LINQ using the Entity Framework (EDM).
What about this approach:
Func<Record, object> sort1 = r => GetProperty(r, "City");
Func<Record, object> sort2 = r => GetProperty(r, "State");
Func<Record, object> sort3 = r => GetProperty(r, "Address");
Func<Record, bool> filterPredicate = p => GetProperty(p, "City").ToString().StartsWith("A");
IEnumerable<Record> enumerable = list.Where(filterPredicate)
.OrderBy(sort1)
.ThenBy(sort2).
.ThenBy(sort3);
Where GetProperty is implemented as:
static object GetProperty(Record record, string paramName)
{
if (paramName == "City") return record.City;
if (paramName == "State") return record.State;
if (paramName == "Address") return record.Address;
if (paramName == "CustomerId") return record.CustomerId;
throw new InvalidEnumArgumentException();
}
You should make your query dynamic, and when make dynamic query you should use (Exec ) command on SQL to execute your dynamic query.
Thats it :D
But you should notice that execute command is not that good for performance issues.

Resources