Project DescriptionLINQ provider built on top of System.DirectoryServices.Protocols for querying and updating LDAP servers.
NuGet Package
Features
- Translates lamda expressions into LDAP filters according to RFC4515.
- Ad hoc querying using anonymous types or custom DirectoryAttributes class.
- Fluent mapping and configuration.
For more features see the
Documentation
C# Mapped Objects
[DirectorySchema("CN=Users,CN=Employees,DC=Northwind,DC=local", ObjectClass = "User")]
public class User : DirectoryObjectBase
{
private string _title;
[DistinguishedName]
public string DistinguishedName { get; set; }
[DirectoryAttribute("cn", ReadOnly = true)]
public string CommonName { get; set; }
[DirectoryAttribute]
public string Title
{
get { return _title; }
set
{
_title = value;
AttributeChanged("Title");
}
}
[DirectoryAttribute(StoreGenerated = true)]
public Guid ObjectGuid { get; set; }
[DirectoryAttribute(StoreGenerated = true)]
public SecurityIdentifier ObjectSid { get; set; }
[DirectoryAttribute(StoreGenerated = true)]
public DateTime WhenChanged { get; set; }
}
var factory = new LdapConnectionFactory("myserver.com");
using (var context = new DirectoryContext(factory.GetConnection(), disposeOfConnection: true))
{
context.Log = Console.Out;
var user = context.Query<User>()
.Where(u => u.CommonName == "Andrew Fuller")
.FirstOrDefault();
Console.WriteLine(user.WhenChanged);
user.Title = "Just Promoted";
User updated = context.Update(user);
Console.WriteLine(updated.WhenChanged);
}
C# Dynamic Querying
var factory = new LdapConnectionFactory("myserver.com");
using (var context = new DirectoryContext(factory.GetConnection(), disposeOfConnection: true))
{
context.Log = Console.Out;
IDirectoryAttributes user = context.Query("CN=Users,CN=Employees,DC=Northwind,DC=local", objectClass: "User")
.Where("givenname=Andrew")
.Where(da => Filter.Equal(da, "sn", "Fuller"))
.FirstOrDefault();
Console.WriteLine(user.GetDateTime("WhenChanged"));
user.Set("title", "Just Promoted");
IDirectoryAttributes updated = context.Update(user);
Console.WriteLine(user.GetDateTime("WhenChanged"));
}
C# Query By Example
var factory = new LdapConnectionFactory("myserver.com");
using (var context = new DirectoryContext(factory.GetConnection(), disposeOfConnection: true))
{
context.Log = Console.Out;
var example = new
{
DistinguishedName = "",
Cn = "",
Title = "",
ObjectGuid = default(Guid),
ObjectSid = default(SecurityIdentifier),
WhenChanged = default(DateTime)
};
var user = context.Query(example, "CN=Users,CN=Employees,DC=Northwind,DC=local", objectClass: "User")
.Where(u => u.Cn == "Andrew Fuller")
.FirstOrDefault();
Console.WriteLine(user.WhenChanged);
var toUpdate = new { Title = "Just Promoted" };
var updated = context.Update(user.DistinguishedName, toUpdate.ToDictionary());
Console.WriteLine(updated.WhenChanged);
}
VB Mapped Objects
<DirectorySchema("CN=Users,CN=Employees,DC=Northwind,DC=local")>
Public Class User
Inherits DirectoryObjectBase
Private _title As String
<DistinguishedName()>
Public Property DistinguishedName As String
<DirectoryAttribute("cn", ReadOnly = true)>
Public Property CommonName As String
<DirectoryAttribute()>
Public Property Title As String
Get
Return _title
End Get
Set(value As String)
_title = value
AttributeChanged("Title")
End Set
End Property
<DirectoryAttribute(StoreGenerated:=True)>
Public Property ObjectGuid As Guid
<DirectoryAttribute(StoreGenerated:=True)>
Public Property SecurityIdentifier As SecurityIdentifier
<DirectoryAttribute(StoreGenerated:=True)>
Public Property WhenChanged As DateTime
End Class
Dim factory As New LdapConnectionFactory("myserver.com")
Using context As New DirectoryContext(factory.GetConnection(), True)
context.Log = Console.Out
Dim user = context.Query(Of User)() _
.Where(Function(u As User) u.CommonName.Equals("Andrew Fuller")) _
.FirstOrDefault()
Console.WriteLine(user.WhenChanged)
user.Title = "Just Promoted"
Dim updated = context.Update(user)
Console.WriteLine(updated.WhenChanged)
End Using
VB Dynamic Querying
Dim factory As New LdapConnectionFactory("myserver.com")
Using context As New DirectoryContext(factory.GetConnection(), True)
context.Log = Console.Out
Dim user = context.Query("CN=Users,CN=Employees,DC=Northwind,DC=local", objectClass:="User") _
.Where("givenname=Andrew") _
.Where(Function(da As IDirectoryAttributes) Filter.Equal(da, "sn", "Fuller")) _
.FirstOrDefault()
Console.WriteLine(user.GetDateTime("whenchanged"))
user.Set("title", "Just Promoted")
Dim updated = context.Update(user)
Console.WriteLine(user.GetDateTime("whenchanged"))
End Using
VB Query By Example
Dim factory As New LdapConnectionFactory("myserver.com")
Using context As New DirectoryContext(factory.GetConnection(), True)
context.Log = Console.Out
Dim example = New With
{
.DistinguishedName = "",
.Cn = "",
.Title = "",
.ObjectGuid = DirectCast(Nothing, Nullable(Of Guid)),
.ObjectSid = DirectCast(Nothing, SecurityIdentifier),
.WhenChanged = DirectCast(Nothing, Nullable(Of DateTime))
}
Dim user = context.Query(example, "CN=Users,CN=Employees,DC=Northwind,DC=local", objectClass:="User") _
.Where("cn=Andrew Fuller") _
.FirstOrDefault()
Console.WriteLine(user.WhenChanged)
Dim toUpdate = New With {.Title = "Just Promoted"}
Dim updated = context.Update(user.DistinguishedName, toUpdate.ToDictionary())
Console.WriteLine(updated.WhenChanged)
End Using
Tested Servers
- Microsoft Lightweight Directory Services
- Microsoft Active Directory
- IBM Tivoli Directory
- Siemens DirX
- Apache Directory (minor testing)
Disclaimer
This project is provided as is. I have tested the project primarily using Lightweight Directory Services, but servers behave differently. I recommend thorough testing before using this project in a production environment.
Visit my blog:
http://hattercoding.blogspot.com/.