472,811 Members | 1,883 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,811 software developers and data experts.

Using Generics with System.DirectoryServices

Hi,

I'm in the process of updating an ASP.NET v1.1 web app to v2. The app uses
ActiveDirectory a great deal, and I'm trying to use the new
System.Collections.Generic namespace where possible, having been advised by
several luminaries that that is a "good thing to do"... :-)

However, I'm experiencing a problem with the IEnumerable interface. (N.B. I
understand fully that I should be using the LDAP provider instead of the
WinNT provider - I'm in the process of fixing that too, but that's not my
most pressing problem.)

I use the following function to return a list of all users in a group:

using System;
using System.Collections;
using System.Collections.Generic;
using System.DirectoryServices;

public static List<stringGetGroupsForUser(string pstrUser)
{
DirectoryEntry objADEntry = null;
DirectoryEntry objUser = null;
object objChildren = null;
List<stringlstGroups = new List<string>();

try
{
objADEntry = new DirectoryEntry("WinNT://" + mstrDomain + ",
domain");
objUser = objADEntry.Children.Find(pstrUser, "user");
objChildren = objUser.Invoke("Groups");
foreach (object objChild in (IEnumerable)objChildren)
{
DirectoryEntry objGroup = new DirectoryEntry(objChild);
lstGroups.Add(objGroup.Name.ToLower());
}
return lstGroups;
}
catch (Exception)
{
throw;
}
}
It works well enough. However, when I rem out the using System.Collections;
namespace reference, the code fails and tells me that there is no support
for IEnumerable taking no arguments. Fair enough.

If I amend the line in question to:

foreach (object objChild in (IEnumerable<DirectoryEntries>)objChildren)

That returns the following error:

Unable to cast COM object of type 'System.__ComObject' to interface type
'System.Collections.Generic.IEnumerable`1[System.DirectoryServices.DirectoryEntries]'.
This operation failed because the QueryInterface call on the COM component
for the interface with IID '{AEF9EC8A-1E73-365B-8DA2-800A3A6166E6}' failed
due to the following
error: No such interface supported (Exception from HRESULT: 0x80004002
(E_NOINTERFACE)).
At this point, I'm pretty much out of my depth. Therefore, I'd be grateful
to know:

1) if what I'm doing is a worthwhile exercise, or whether I should just
continue with the old IEnumerable object in the old System.Collections
namespace

2) apart from replacing WinNT with LDAP, which I'm in the process of doing,
is there a more efficient method for returning a list of groups to which a
user belongs?
Any assistance gratefully received.

Mark
Oct 10 '06 #1
6 4000
All of my apps that use AD are still on .NET 1.1, but to the best of my
knowledge there have been a number of changes to DirectoryServices in
..net 2.0

First, I never used the WinNT objects, I always used LDAP. I didn't
need backwards compatibility and it just worked the first time I tried
it, so in that sense I'm not sure how the WinNT query prefix works

For more information on DirectoryServices take a look here:

http://msdn.microsoft.com/library/de..._providers.asp

that link talks about the ADSI providers which probably supports
generics. The method your trying doesn't seem to support generics,
especially since it seems to be returning a COM object.

hope that helps!

sean

Mark Rae wrote:
Hi,

I'm in the process of updating an ASP.NET v1.1 web app to v2. The app uses
ActiveDirectory a great deal, and I'm trying to use the new
System.Collections.Generic namespace where possible, having been advised by
several luminaries that that is a "good thing to do"... :-)

However, I'm experiencing a problem with the IEnumerable interface. (N.B. I
understand fully that I should be using the LDAP provider instead of the
WinNT provider - I'm in the process of fixing that too, but that's not my
most pressing problem.)

I use the following function to return a list of all users in a group:

using System;
using System.Collections;
using System.Collections.Generic;
using System.DirectoryServices;

public static List<stringGetGroupsForUser(string pstrUser)
{
DirectoryEntry objADEntry = null;
DirectoryEntry objUser = null;
object objChildren = null;
List<stringlstGroups = new List<string>();

try
{
objADEntry = new DirectoryEntry("WinNT://" + mstrDomain + ",
domain");
objUser = objADEntry.Children.Find(pstrUser, "user");
objChildren = objUser.Invoke("Groups");
foreach (object objChild in (IEnumerable)objChildren)
{
DirectoryEntry objGroup = new DirectoryEntry(objChild);
lstGroups.Add(objGroup.Name.ToLower());
}
return lstGroups;
}
catch (Exception)
{
throw;
}
}
It works well enough. However, when I rem out the using System.Collections;
namespace reference, the code fails and tells me that there is no support
for IEnumerable taking no arguments. Fair enough.

If I amend the line in question to:

foreach (object objChild in (IEnumerable<DirectoryEntries>)objChildren)

That returns the following error:

Unable to cast COM object of type 'System.__ComObject' to interface type
'System.Collections.Generic.IEnumerable`1[System.DirectoryServices.DirectoryEntries]'.
This operation failed because the QueryInterface call on the COM component
for the interface with IID '{AEF9EC8A-1E73-365B-8DA2-800A3A6166E6}' failed
due to the following
error: No such interface supported (Exception from HRESULT: 0x80004002
(E_NOINTERFACE)).
At this point, I'm pretty much out of my depth. Therefore, I'd be grateful
to know:

1) if what I'm doing is a worthwhile exercise, or whether I should just
continue with the old IEnumerable object in the old System.Collections
namespace

2) apart from replacing WinNT with LDAP, which I'm in the process of doing,
is there a more efficient method for returning a list of groups to which a
user belongs?
Any assistance gratefully received.

Mark
Oct 10 '06 #2
"Sean Chambers" <dk****@gmail.comwrote in message
news:11**********************@m7g2000cwm.googlegro ups.com...
The method your trying doesn't seem to support generics,
especially since it seems to be returning a COM object.
Er, my method is returning a List<stringobject...
hope that helps!
I'm afraid it doesn't really... But it's the only reply I've had, so thanks
for that... :-)
Oct 10 '06 #3
The method your trying doesn't seem to support generics,
especially since it seems to be returning a COM object.

Er, my method is returning a List<stringobject...
I was referring to the foreach where you are trying to cast a COM
object to a string.

I don't have any experience with com, perhaps I am confused?

Oct 10 '06 #4

"Mark Rae" <ma**@markNOSPAMrae.comwrote in message
news:%2******************@TK2MSFTNGP02.phx.gbl...
| Hi,
|
| I'm in the process of updating an ASP.NET v1.1 web app to v2. The app uses
| ActiveDirectory a great deal, and I'm trying to use the new
| System.Collections.Generic namespace where possible, having been advised
by
| several luminaries that that is a "good thing to do"... :-)
|
| However, I'm experiencing a problem with the IEnumerable interface. (N.B.
I
| understand fully that I should be using the LDAP provider instead of the
| WinNT provider - I'm in the process of fixing that too, but that's not my
| most pressing problem.)
|
| I use the following function to return a list of all users in a group:
|
| using System;
| using System.Collections;
| using System.Collections.Generic;
| using System.DirectoryServices;
|
| public static List<stringGetGroupsForUser(string pstrUser)
| {
| DirectoryEntry objADEntry = null;
| DirectoryEntry objUser = null;
| object objChildren = null;
| List<stringlstGroups = new List<string>();
|
| try
| {
| objADEntry = new DirectoryEntry("WinNT://" + mstrDomain + ",
| domain");
| objUser = objADEntry.Children.Find(pstrUser, "user");
| objChildren = objUser.Invoke("Groups");
| foreach (object objChild in (IEnumerable)objChildren)
| {
| DirectoryEntry objGroup = new DirectoryEntry(objChild);
| lstGroups.Add(objGroup.Name.ToLower());
| }
| return lstGroups;
| }
| catch (Exception)
| {
| throw;
| }
| }
|
|
| It works well enough. However, when I rem out the using
System.Collections;
| namespace reference, the code fails and tells me that there is no support
| for IEnumerable taking no arguments. Fair enough.
|
| If I amend the line in question to:
|
| foreach (object objChild in (IEnumerable<DirectoryEntries>)objChildren)
|
| That returns the following error:
|
| Unable to cast COM object of type 'System.__ComObject' to interface type
|
'System.Collections.Generic.IEnumerable`1[System.DirectoryServices.DirectoryEntries]'.
| This operation failed because the QueryInterface call on the COM component
| for the interface with IID '{AEF9EC8A-1E73-365B-8DA2-800A3A6166E6}' failed
| due to the following
| error: No such interface supported (Exception from HRESULT: 0x80004002
| (E_NOINTERFACE)).
|
|
| At this point, I'm pretty much out of my depth. Therefore, I'd be grateful
| to know:
|
| 1) if what I'm doing is a worthwhile exercise, or whether I should just
| continue with the old IEnumerable object in the old System.Collections
| namespace
|
| 2) apart from replacing WinNT with LDAP, which I'm in the process of
doing,
| is there a more efficient method for returning a list of groups to which a
| user belongs?
|
|
| Any assistance gratefully received.
|
| Mark
|
|

WinNT and LDAP (the providers) implement a diferent object model, so you
can't use the following sample to query group membership in a NT4 domain.

// search all groups myUser is member a of.
// use server or FastBind binding for the fastest way to query the AD.
using(DirectoryEntry user = new DirectoryEntry("LDAP://..., cn=myUser,
cn=.., dn=..", AuthenticationTypes.FastBind))
{
PropertyCollection pcoll = user.Properties;
PropertyValueCollection memberOf = pcoll["memberOf"];
foreach(string group in memberOf)
lstGroups.Add(group);
}

note also that the AD hierarchy differs considerable from NT4's SAM object
model, so the data returned is in the "common name "format (that is :
CN=...) instead of a simple SAM account name.

Willy.
Oct 10 '06 #5
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:eU**************@TK2MSFTNGP05.phx.gbl...
WinNT and LDAP (the providers) implement a diferent object model, so you
can't use the following sample to query group membership in a NT4 domain.
That's fine - it's a Win2k3 domain.
using(DirectoryEntry user = new DirectoryEntry("LDAP://..., cn=myUser,
cn=.., dn=..", AuthenticationTypes.FastBind))
That generates an error saying that there's no overload for DirectoryEntry
taking 2 arguments...

However, I'll perservere... :-)
Oct 10 '06 #6
"Mark Rae" <ma**@markNOSPAMrae.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
However, I'll perservere... :-)
Persevered and succeeded :-) New code, with the added advantage of having
removed the reliance on the WinNT provider, follows:

public static List<stringGetGroupsForUser(string pstrUser)
{
DirectorySearcher objDS = null;
SearchResult objSR = null;
DirectoryEntry objUser = null;
List<stringlstGroups = new List<string>();

try
{
objDS = new DirectorySearcher("objectCategory=User");
objDS.Filter = "(SAMAccountName=" + pstrUser + ")";
objSR = objDS.FindOne();
objUser = new DirectoryEntry(objSR.Path);

PropertyCollection colProperties = objUser.Properties;
PropertyValueCollection colPropertyValues =
colProperties["memberOf"];
foreach (string strGroup in colPropertyValues)
{
lstGroups.Add(GetSAMAccountName(strGroup).ToLower( ));
}
return lstGroups;
}
catch (Exception)
{
throw;
}
}

GetSAMAccountName is, as its name suggests, another method in my ADSI
wrapper class which takes an LDAP path and returns the SAMAccountName -
thanks again for your help.
Oct 10 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Corne Grotius | last post by:
Hiya, I'm trying to create a new site on IIS 6.0 using ADSI and C# using the following code: DirectoryEntry W3SVC = new DirectoryEntry("IIS://" + ServerName + "/w3svc", Username, Password,...
1
by: Prasad Karunakaran | last post by:
I am using the C# DirectoryEntry class to retrieve the Properties of an user object in the Active Directory. I need to get the First Name and Last Name as properties. I know it is not supported...
1
by: Siddharth Jain | last post by:
hello I am trying to enumerate the shared folders on a server using the NetShareEnum function. Now, when the server has a password set to access the shared folders, the function returns system...
8
by: Sameh Ahmed | last post by:
Hello there I need to get a list of domain controllers to a domain I bind too using it's name rather than the DN. I am trying a query looking for objectClass=nTDSDSA but this returns 0 results I...
1
by: sudhapadmas | last post by:
Hello netters, I was trying to create a virtual directory in IIS using the following code: System.EnterpriseServices.Internal.IISVirtualRoot vr = new...
2
by: Jay | last post by:
Hi, This is Jay Mehta. I have this problem when using LDAP. I extract names and EmailId's of all those present from LDAP and populate in a datagrid. Now when run locally, it is running...
0
by: RSH | last post by:
I am using System.DirectoryServices to query our AD in order to get information about users. I am having problems understanding how to get at the Username and the Email address (to begin with) ...
2
by: DavidADEW | last post by:
need a ASP.NET C# web page that lets a user enter their NT user name and password and passes to NT to see if they are a valid NT login. I am aware of the System.DirectoryServices.DirectoryEntry...
0
by: Big Charles | last post by:
Hello, Programming in VS2003-ASP.NET 1.1, I have this problem: Using DirectoryEntry and without any admin user, how can I check if a domain account, that try to login, has expired? Scenario: User...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.