473,474 Members | 1,884 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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 4056
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.