अन्य उत्तर खराब वर्णित किया गया है, कैसे का वर्णन नहीं किया उन्हें लागू करने के लिए, और अधिकांश ने गलत फिल्टर गुण दिए। तुम भी .Filter
उपयोग करने की आवश्यकता नहीं है - तुम सिर्फ एक PrincipalSearcher
जो कुछ भी स्थिति में है कि खोज से चलाता है का उपयोग करते हुए उस वस्तु पर खोज करते हैं, एक UserPrincipal
वस्तु को अपने गुण (अंतिम नाम = .Surname
, प्रथम नाम = .GivenName
) या लेन-तब:
string firstName = txtFirstName.Text;
string lastName = txtLastName.Text;
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal up = new UserPrincipal(ctx);
if (!String.IsNullOrEmpty(firstName))
up.GivenName = firstName;
if (!String.IsNullOrEmpty(lastName))
up.Surname = lastName;
PrincipalSearcher srch = new PrincipalSearcher(up);
srch.QueryFilter = up;
मैं यह सोचते कर रहा हूँ आप के साथ txtFirstName
और txtLastName
की आईडी/नाम इसे पाने के लिए प्रथम और अंतिम नाम के लिए बक्सें है,। ध्यान दें कि यदि आपके पास उस संपत्ति में कोई मूल्य नहीं है जिसे आप ढूंढ रहे हैं, तो इसे UserPrincipal
पर न जोड़ें, या यह अपवाद का कारण बन जाएगा। ऊपर दिए गए चेक के लिए यही कारण है।
फिर आप srch
पर एक .FindAll
कर Principal
वस्तुओं की एक PrincipalSearchResult
संग्रह में खोज परिणामों को प्राप्त करने के लिए:
using (PrincipalSearchResult<Principal> results = srch.FindAll())
{
if (results != null)
{
int resultCount = results.Count();
if (resultCount > 0) // we have results
{
foreach (Principal found in results)
{
string username = found.SamAccountName; // Note, this is not the full user ID! It does not include the domain.
}
}
}
}
ध्यान दें कि परिणाम अशक्त नहीं होगा, भले ही इसके .Count()
0
है, और क्यों दोनों चेकों हैं क्या आप वहां मौजूद हैं।
आपको लगता है कि foreach
गुण आप की जरूरत प्राप्त करने के लिए का उपयोग कर पुनरावृति, और यह कैसे सी # का उपयोग कर ई में एक उपयोगकर्ता को खोजने के लिए की सवाल का जवाब है, लेकिन ध्यान दें कि आप केवल Principal
वस्तु का उपयोग कर कुछ संपत्तियों के लिए प्राप्त कर सकते हैं, और अगर मैं Google के माध्यम से इस प्रश्न पर पहुंचे (जैसा मैंने किया), मैं बहुत निराश होगा। यदि आपको लगता है कि आपको बस इतना ही चाहिए - बढ़िया, आप कर चुके हैं! लेकिन बाकी को पाने के लिए (और अपनी खुद की विवेक को आराम दें), आपको नीचे उतरना होगा, और मैं वर्णन करूंगा कि यह कैसे करें।
मैंने पाया कि आप ऊपर दिए गए username
का उपयोग नहीं कर सकते हैं, लेकिन आपको पूरे DOMAIN\doej
नाम का नाम प्राप्त करना होगा। इस तरह आप ऐसा करते हैं। इस समारोह
private static string GetUserIdFromPrincipal(Principal prin)
{
string upn = prin.UserPrincipalName;
string domain = upn.Split('@')[1];
domain = domain.Substring(0, domain.IndexOf(".YOURDOMAIN"));
// "domain" will be the subdomain the user belongs to.
// This may require edits depending on the organization.
return domain + @"\" + prin.SamAccountName;
}
एक बार जब आप गए हैं, आपको कॉल कर सकते हैं: इसके बजाय, कि foreach
पाश में इस डाल से ऊपर,: और
string userId = GetUserIdFromPrincipal(found);
इस फ़ंक्शन का उपयोग
public static string[] GetUserProperties(string strUserName)
{
UserPrincipal up = GetUser(strUserName);
if (up != null)
{
string firstName = up.GivenName;
string lastName = up.Surname;
string middleInit = String.IsNullOrEmpty(up.MiddleName) ? "" : up.MiddleName.Substring(0, 1);
string email = up.EmailAddress;
string location = String.Empty;
string phone = String.Empty;
string office = String.Empty;
string dept = String.Empty;
DirectoryEntry de = (DirectoryEntry)up.GetUnderlyingObject();
DirectorySearcher ds = new DirectorySearcher(de);
ds.PropertiesToLoad.Add("l"); // city field, a.k.a location
ds.PropertiesToLoad.Add("telephonenumber");
ds.PropertiesToLoad.Add("department");
ds.PropertiesToLoad.Add("physicalDeliveryOfficeName");
SearchResultCollection results = ds.FindAll();
if (results != null && results.Count > 0)
{
ResultPropertyCollection rpc = results[0].Properties;
foreach (string rp in rpc.PropertyNames)
{
if (rp == "l") // this matches the "City" field in AD properties
location = rpc["l"][0].ToString();
if (rp == "telephonenumber")
phone = FormatPhoneNumber(rpc["telephonenumber"][0].ToString());
if (rp == "physicalDeliveryOfficeName")
office = rpc["physicalDeliveryOfficeName"][0].ToString();
if (rp == "department")
dept = rpc["department"][0].ToString();
}
}
string[] userProps = new string[10];
userProps[0] = strUserName;
userProps[1] = firstName;
userProps[2] = lastName;
userProps[3] = up.MiddleName;
userProps[4] = middleInit;
userProps[5] = email;
userProps[6] = location;
userProps[7] = phone;
userProps[8] = office;
userProps[9] = dept;
return userProps;
}
else
return null;
}
/// <summary>
/// Returns a UserPrincipal (AD) user object based on string userID being supplied
/// </summary>
/// <param name="strUserName">String form of User ID: domain\username</param>
/// <returns>UserPrincipal object</returns>
public static UserPrincipal GetUser(string strUserName)
{
PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain);
try
{
UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext, strUserName);
return oUserPrincipal;
}
catch (Exception ex) { return null; }
}
public static string FormatPhoneNumber(string strPhoneNumber)
{
if (strPhoneNumber.Length > 0)
// return String.Format("{0:###-###-####}", strPhoneNumber); // formating does not work because strPhoneNumber is a string and not a number
return Regex.Replace(strPhoneNumber, @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");
else
return strPhoneNumber;
}
ध्यान दें कि FormatPhoneNumber
फ़ंक्शन उत्तरी अमेरिकी संख्याओं के लिए है। यह एक संख्या लेगा (##########
) और इसे ###-###-####
में अलग करें।,
string[] userProps = GetUserProperties(userId);
string office = userProps[8];
लेकिन एक पूरे के समाधान के रूप में, आप भी इन परिणामों एक DataRow
स्तंभ में जोड़ सकते हैं, और के रूप में यह वापसी:
फिर आप गुण इस तरह कि foreach
पाश में प्राप्त कर सकते हैं, वापस DataTable
का हिस्सा जिसे आप ListView
या GridView
से जोड़ सकते हैं।
/// <summary>
/// Gets matches based on First and Last Names.
/// This function takes a list of acceptable properties:
/// USERNAME
/// MIDDLE_NAME
/// MIDDLE_INITIAL
/// EMAIL
/// LOCATION
/// POST
/// PHONE
/// OFFICE
/// DEPARTMENT
///
/// The DataTable returned will have columns with these names, and firstName and lastName will be added to a column called "NAME"
/// as the first column, automatically.
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <param name="props"></param>
/// <returns>DataTable of columns from "props" based on first and last name results</returns>
public static DataTable GetUsersFromName(string firstName, string lastName, List<string> props)
{
string userId = String.Empty;
int resultCount = 0;
DataTable dt = new DataTable();
DataRow dr;
DataColumn dc;
// Always set the first column to the Name we pass in
dc = new DataColumn();
dc.DataType = System.Type.GetType("System.String");
dc.ColumnName = "NAME";
dt.Columns.Add(dc);
// Establish our property list as columns in our DataTable
if (props != null && props.Count > 0)
{
foreach (string s in props)
{
dc = new DataColumn();
dc.DataType = System.Type.GetType("System.String");
if (!String.IsNullOrEmpty(s))
{
dc.ColumnName = s;
dt.Columns.Add(dc);
}
}
}
// Start our search
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal up = new UserPrincipal(ctx);
if (!String.IsNullOrEmpty(firstName))
up.GivenName = firstName;
if (!String.IsNullOrEmpty(lastName))
up.Surname = lastName;
PrincipalSearcher srch = new PrincipalSearcher(up);
srch.QueryFilter = up;
using (PrincipalSearchResult<Principal> results = srch.FindAll())
{
if (results != null)
{
resultCount = results.Count();
if (resultCount > 0) // we have results
{
foreach (Principal found in results)
{
// Iterate results, set into DataRow, add to DataTable
dr = dt.NewRow();
dr["NAME"] = found.DisplayName;
if (props != null && props.Count > 0)
{
userId = GetUserIdFromPrincipal(found);
// Get other properties
string[] userProps = GetUserProperties(userId);
foreach (string s in props)
{
if (s == "USERNAME")
dr["USERNAME"] = userId;
if (s == "MIDDLE_NAME")
dr["MIDDLE_NAME"] = userProps[3];
if (s == "MIDDLE_INITIAL")
dr["MIDDLE_INITIAL"] = userProps[4];
if (s == "EMAIL")
dr["EMAIL"] = userProps[5];
if (s == "LOCATION")
dr["LOCATION"] = userProps[6];
if (s == "PHONE")
dr["PHONE"] = userProps[7];
if (s == "OFFICE")
dr["OFFICE"] = userProps[8];
if (s == "DEPARTMENT")
dr["DEPARTMENT"] = userProps[9];
}
}
dt.Rows.Add(dr);
}
}
}
}
return dt;
}
आप इस तरह इस समारोह कहेंगे:
string firstName = txtFirstName.Text;
string lastName = txtLastName.Text;
List<string> props = new List<string>();
props.Add("OFFICE");
props.Add("DEPARTMENT");
props.Add("LOCATION");
props.Add("USERNAME");
DataTable dt = GetUsersFromName(firstName, lastName, props);
DataTable
, उन स्तंभों से भर दिया जाएगा और इस तरह मैंने किया, एक List<string>
गुण मैं जरूरत से भर में भेज रहा है पहले कॉलम के रूप में NAME
कॉलम, जिसमें उपयोगकर्ता के वास्तविक .DisplayName
एडी से होंगे।
नोट: आप System.DirectoryServices
और System.DirectoryServices.AccountManagement
, System.Text.RegularExpressions
, System.Data
यह सब का उपयोग करने के संदर्भ होना चाहिए।
एचटीएच!
नीचे जवाब पढ़ें सब के बारे में sAMAccountName का उपयोग कर, और मैं नहीं जानता कि क्यों वे इतने सारे upvotes है कर रहे हैं: यही कारण है कि है। यह प्रश्न गुण प्राप्त करने के लिए पहले और अंतिम नाम का उपयोग करने के बारे में है! केवल शीर्ष/चिह्नित सही उत्तर भी करीब है। – vapcguy