5

While asynchronously requesting the execution of LDAP operations via BeginSendRequest and EndSendRequest is pretty straightforward, I was not able to identify how the binding-process can be done asynchronously.

Is there a possibility to bind asynchronously with the LdapConnection of SDS.P

sds
  • 58,617
  • 29
  • 161
  • 278
HCL
  • 36,053
  • 27
  • 163
  • 213
  • Seems like there is no async binding support for LdapConnection class. However you can write a couple of extension methods like BeginBind\EndBind. In BeginBind method create an Action delegate for connection.Bind and call its BeginInvoke method. In EndBind cast IAsyncResult to AsyncResult to retrieve its AsyncDelegate property. Callback method can also easily be added to BeginBind if required – oldovets Dec 24 '16 at 16:46
  • Hi @oldovets, when you say "seems like there is no async binding support for LdapConnection class." - are you 100% sure about that? Do you have an online reference you can't point us too? Just curious...that's all. – T-Heron Dec 24 '16 at 16:51
  • 2
    @T-Heron: My claim is based on LdapConnection class documentation: https://msdn.microsoft.com/en-us/library/system.directoryservices.protocols.ldapconnection(v=vs.110).aspx – oldovets Dec 24 '16 at 17:06
  • @oldovets, kudos, and a little up-vote to your comment. :-) – T-Heron Dec 24 '16 at 17:12

1 Answers1

1

Was looking to do async LDAP operations and found this unanswered question. Ended up figuring it out myself:

Edit: This still doesnt seem to work 100%. It seems BeginSendRequest() will actually block while looking for an endpoint / Domain Controller / LDAP server using this method. Found this out later the hard way when network config made the server unavailable. I ended up just using the synchronous stuff inside a Task.Run() and moved on with my life.

Assuming that you also want to send/receive a LDAP request asynchronously after Binding (not sure why else you would want to Bind), you can use the AutoBind property on LdapConnection and specify credentials up front in the constructor to achieve an "Asynchronous Bind", by using BeginSendRequest()/EndSendRequest() and letting it handle the Bind internally, in an asynchronous manner.

using System.DirectoryServices.Protocols;
using System.Net;
using System.Threading.Tasks;

// ...

using (var connection = 
    new LdapConnection(
        new LdapDirectoryIdentifier("fqdn.example.com", true, false),
        new NetworkCredential("someuser", "somepassword"),
        AuthType.Basic))
{
    // The Answer...
    connection.AutoBind = true;

    var searchResult = await Task.Factory.FromAsync(
            connection.BeginSendRequest, 
            connection.EndSendRequest,
            new SearchRequest(
                "DC=example,DC=com",
                "(objectClass=user)",
                SearchScope.Subtree,
                "distinguishedname"), 
            PartialResultProcessing.NoPartialResultSupport, 
            null);

    // Profit
}

For brevity, I put the older Asynchronous Programming Model methods (APM) on LdapConnection into the handy wrapper method provided for Task-based Asynchronous Pattern (TAP) so that it may be simply await'ed as expected in modern .Net projects. See: https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/interop-with-other-asynchronous-patterns-and-types

Doesn't really answer the question precisely, but does show that you don't really have to Bind explicitly yourself and maybe that's why MS didn't bother adding a BeginBind() etc. Hope this helps the next weary programmer wrestling with LDAP interop who comes across it.

Bryan W
  • 163
  • 1
  • 7