我正在使用角电抗形式的输入搜索字段来查找AD用户。因此,当您开始输入名称时,您将获得该字段的一些自动完成选项。为此,我从我的角度应用程序中调用了一个Web api方法,这反过来又向我返回了用户列表。我将该用户列表绑定到输入字段数据列表。我在Web API中使用以下代码:-
public List<string> ADUsers()
{
List<string> users = new List<string>();
using (var context = new PrincipalContext(ContextType.Domain, "abc.in"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
if(de.Properties["givenName"].Value != null && de.Properties["sn"].Value != null)
users.Add(de.Properties["givenName"].Value + " " + de.Properties["sn"].Value);
}
}
}
return users;
}
由于用户数量太多,将列表返回到angular(20-25 secs)需要花费一些时间,而这又需要花费时间才能反映在反应形式输入字段中。我是无经验的,基本上是.net开发人员。您能否提出一些方法来找出一些响应式解决方案?或者是否有可能具有角度本身的功能,这样我就不应该为此调用web api方法?
答案 0 :(得分:2)
我在您的代码中看到几个问题:
PrincipalSearcher
和整个System.DirectoryServices.AccountManagement
名称空间不是很有效。例如,在这种情况下,即使您仅使用名字和姓氏,它也会为在幕后找到的每个结果加载每个属性。通过直接使用System.DirectoryServices
命名空间(DirectorySearcher
/ DirectoryEntry
,无论如何,AccountManagement
命名空间在幕后都可以使用),您可以做得更好。以下是适合您的情况的示例:
public List<string> ADUsers(string filter) {
if (string.IsNullOrEmpty(filter)) throw new ArgumentNullException(nameof(filter));
List<string> users = new List<string>();
var ds = new DirectorySearcher(
new DirectoryEntry("LDAP://abc.in"), //domain to search
$"(&(objectClass=user)(anr={filter}))", //search filter
new[] { "givenName", "sn" }) //attributes to load
{
SizeLimit = 25 //change this depending on how many you want to show
};
using (var results = ds.FindAll()) {
foreach (SearchResult result in results) {
users.Add($"{result.Properties["givenName"][0]} {result.Properties["sn"][0]}");
}
}
return users;
}
您可以将其任何部分名称作为filter
传递给它,并且它使用AD中称为Ambiguous Name Resolution的功能来查找用户。这将在名字,姓氏和其他属性(该文档中的完整列表)中查找部分匹配项。
我也将结果限制为25,但是您可以根据需要更改它。
此方法还告诉AD 仅为每个结果返回givenName
和sn
属性,因为这就是我们关心的全部。这将减少您的应用程序与域控制器之间的网络流量。
答案 1 :(得分:0)
我在方法中也应用了过滤器,而且速度非常快。代码如下:-
public List<string> ADUsers(string filter)
{
List<string> users = new List<string>();
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "abc.in");
UserPrincipal user = new UserPrincipal(domainContext)
{
GivenName = filter + "*"
};
PrincipalSearcher pS = new PrincipalSearcher
{
QueryFilter = user
};
PrincipalSearchResult<Principal> results = pS.FindAll();
List<Principal> pc = results.ToList();
foreach (Principal p in pc)
{
DirectoryEntry de = (DirectoryEntry)p.GetUnderlyingObject();
if (de.Properties["givenName"].Value != null && de.Properties["sn"].Value != null)
users.Add(de.Properties["givenName"].Value + " " + de.Properties["sn"].Value);
}
return users;
}
我认为使用System.DirectoryServices.AccountManagement不会出现任何性能问题,并且对我来说效果很好。我仍然将加百列的答案标记为正确答案(应用过滤器的想法)。