.NET LDAP 路径实用程序 (C#)

发布于 2024-08-04 11:28:25 字数 491 浏览 3 评论 0原文

是否有用于 LDAP 路径操作的 .NET 库?
我想要有一些类似于 System.IO.Path 的东西,允许例如做类似的事情

string ou1 = LDAPPath.Combine("OU=users","DC=x,DC=y");
string ou2 = LDAPPath.Parent("CN=someone,OU=users,DC=x,DC=y");

否则,在 .NET 中处理 LDAP 可分辨名称的常见方法是什么?

为了澄清我的问题:我并不是一般性地询问“.NET 中的目录服务”;而是询问“.NET 中的目录服务”。我已经使用过它并完成了一些程序来执行一些任务。我觉得缺少的是操作路径、解析可分辨名称等的正确方法,并且由于这应该是一个非常常见的需求,所以我希望有一种比分割字符串更干净的方法来做到这一点在逗号 (1) 上。

(1) 例如,调用库中以逗号分隔字符串的函数

Is there a .NET library for LDAP paths manipulations?
I would like to have something equivalent to System.IO.Path, allowing e.g. to do something like

string ou1 = LDAPPath.Combine("OU=users","DC=x,DC=y");
string ou2 = LDAPPath.Parent("CN=someone,OU=users,DC=x,DC=y");

Otherwise, what's the common way to deal with LDAP distinguished names in .NET?

To clarify my question: I'm not asking about "directory services in .NET" in general; I've already worked with that and done some programs to perform some tasks. What I feel is missing is a proper way to manipulate paths, parse distinguished names and so on, and since this should be a pretty common need, I hope there's a cleaner way to do this than split a string on commas(1).

(1) like, for example, calling a function in a library that splits the string on commas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寻梦旅人 2024-08-11 11:28:26

我使用了几个基于 Win32 方法 DsGetRdnW、DsQuoteRdnValueW 和 DsUnquoteRdnValueW 的实用程序类:

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace UnmanagedCode
{
    public class PInvoke
    {
        #region Constants
        public const int ERROR_SUCCESS = 0;
        public const int ERROR_BUFFER_OVERFLOW = 111;
        #endregion Constants

        #region DN Parsing
        [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)]
        protected static extern int DsGetRdnW(
            ref IntPtr ppDN, 
            ref int pcDN, 
            out IntPtr ppKey, 
            out int pcKey, 
            out IntPtr ppVal, 
            out int pcVal
        );

        public static KeyValuePair<string, string> GetName(string distinguishedName)
        {
            IntPtr pDistinguishedName = Marshal.StringToHGlobalUni(distinguishedName);
            try
            {
                IntPtr pDN = pDistinguishedName, pKey, pVal;
                int cDN = distinguishedName.Length, cKey, cVal;

                int lastError = DsGetRdnW(ref pDN, ref cDN, out pKey, out cKey, out pVal, out cVal);

                if(lastError == ERROR_SUCCESS)
                {
                    string key, value;

                    if(cKey < 1)
                    {
                        key = string.Empty;
                    }
                    else
                    {
                        key = Marshal.PtrToStringUni(pKey, cKey);
                    }

                    if(cVal < 1)
                    {
                        value = string.Empty;
                    }
                    else
                    {
                        value = Marshal.PtrToStringUni(pVal, cVal);
                    }

                    return new KeyValuePair<string, string>(key, value);
                }
                else
                {
                    throw new Win32Exception(lastError);
                }
            }
            finally
            {
                Marshal.FreeHGlobal(pDistinguishedName);
            }
        }

        public static IEnumerable<KeyValuePair<string, string>> ParseDN(string distinguishedName)
        {
            List<KeyValuePair<string, string> components = new List<KeyValuePair<string, string>>();
            IntPtr pDistinguishedName = Marshal.StringToHGlobalUni(distinguishedName);
            try
            {
                IntPtr pDN = pDistinguishedName, pKey, pVal;
                int cDN = distinguishedName.Length, cKey, cVal;

                do
                {
                    int lastError = DsGetRdnW(ref pDN, ref cDN, out pKey, out cKey, out pVal, out cVal);

                    if(lastError = ERROR_SUCCESS)
                    {
                        string key, value;

                        if(cKey < 0)
                        {
                            key = null;
                        }
                        else if(cKey == 0)
                        {
                            key = string.Empty;
                        }
                        else
                        {
                            key = Marshal.PtrToStringUni(pKey, cKey);
                        }

                        if(cVal < 0)
                        {
                            value = null;
                        }
                        else if(cVal == 0)
                        {
                            value = string.Empty;
                        }
                        else
                        {
                            value = Marshal.PtrToStringUni(pVal, cVal);
                        }

                        components.Add(new KeyValuePair<string, string>(key, value));

                        pDN = (IntPtr)(pDN.ToInt64() + UnicodeEncoding.CharSize); //skip over comma
                        cDN--;
                    }
                    else
                    {
                        throw new Win32Exception(lastError);
                    }
                } while(cDN > 0);

                return components;
            }
            finally
            {
                Marshal.FreeHGlobal(pDistinguishedName);
            }
        }

        [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)]
        protected static extern int DsQuoteRdnValueW(
            int cUnquotedRdnValueLength,
            string psUnquotedRdnValue,
            ref int pcQuotedRdnValueLength,
            IntPtr psQuotedRdnValue
        );

        public static string QuoteRDN(string rdn)
        {
            if (rdn == null) return null;

            int initialLength = rdn.Length;
            int quotedLength = 0;
            IntPtr pQuotedRDN = IntPtr.Zero;

            int lastError = DsQuoteRdnValueW(initialLength, rdn, ref quotedLength, pQuotedRDN);

            switch (lastError)
            {
                case ERROR_SUCCESS:
                    {
                        return string.Empty;
                    }
                case ERROR_BUFFER_OVERFLOW:
                    {
                        break; //continue
                    }
                default:
                    {
                        throw new Win32Exception(lastError);
                    }
            }

            pQuotedRDN = Marshal.AllocHGlobal(quotedLength * UnicodeEncoding.CharSize);

            try
            {
                lastError = DsQuoteRdnValueW(initialLength, rdn, ref quotedLength, pQuotedRDN);

                switch(lastError)
                {
                    case ERROR_SUCCESS:
                        {
                            return Marshal.PtrToStringUni(pQuotedRDN, quotedLength);
                        }
                    default:
                        {
                            throw new Win32Exception(lastError);
                        }
                }
            }
            finally
            {
                if(pQuotedRDN != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pQuotedRDN);
                }
            }
        }


        [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)]
        protected static extern int DsUnquoteRdnValueW(
            int cQuotedRdnValueLength,
            string psQuotedRdnValue,
            ref int pcUnquotedRdnValueLength,
            IntPtr psUnquotedRdnValue
        );

        public static string UnquoteRDN(string rdn)
        {
            if (rdn == null) return null;

            int initialLength = rdn.Length;
            int unquotedLength = 0;
            IntPtr pUnquotedRDN = IntPtr.Zero;

            int lastError = DsUnquoteRdnValueW(initialLength, rdn, ref unquotedLength, pUnquotedRDN);

            switch (lastError)
            {
                case ERROR_SUCCESS:
                    {
                        return string.Empty;
                    }
                case ERROR_BUFFER_OVERFLOW:
                    {
                        break; //continue
                    }
                default:
                    {
                        throw new Win32Exception(lastError);
                    }
            }

            pUnquotedRDN = Marshal.AllocHGlobal(unquotedLength * UnicodeEncoding.CharSize);

            try
            {
                lastError = DsUnquoteRdnValueW(initialLength, rdn, ref unquotedLength, pUnquotedRDN);

                switch(lastError)
                {
                    case ERROR_SUCCESS:
                        {
                            return Marshal.PtrToStringUni(pUnquotedRDN, unquotedLength);
                        }
                    default:
                        {
                            throw new Win32Exception(lastError);
                        }
                }
            }
            finally
            {
                if(pUnquotedRDN != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUnquotedRDN);
                }
            }
        }
        #endregion DN Parsing
    }

    public class DNComponent
    {
        public string Type { get; protected set; }
        public string EscapedValue { get; protected set; }
        public string UnescapedValue { get; protected set; }
        public string WholeComponent { get; protected set; }

        public DNComponent(string component, bool isEscaped)
        {
            string[] tokens = component.Split(new char[] { '=' }, 2);
            setup(tokens[0], tokens[1], isEscaped);
        }

        public DNComponent(string key, string value, bool isEscaped)
        {
            setup(key, value, isEscaped);
        }

        private void setup(string key, string value, bool isEscaped)
        {
            Type = key;

            if(isEscaped)
            {
                EscapedValue = value;
                UnescapedValue = PInvoke.UnquoteRDN(value);
            }
            else
            {
                EscapedValue = PInvoke.QuoteRDN(value);
                UnescapedValue = value;
            }

            WholeComponent = Type + "=" + EscapedValue;
        }

        public override bool Equals(object obj)
        {
            if (obj is DNComponent)
            {
                DNComponent dnObj = (DNComponent)obj;
                return dnObj.WholeComponent.Equals(this.WholeComponent, StringComparison.CurrentCultureIgnoreCase);
            }
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return WholeComponent.GetHashCode();
        }
    }

    public class DistinguishedName
    {
        public DNComponent[] Components
        {
            get
            {
                return components.ToArray();
            }
        }

        private List<DNComponent> components;
        private string cachedDN;

        public DistinguishedName(string distinguishedName)
        {
            cachedDN = distinguishedName;
            components = new List<DNComponent>();
            foreach (KeyValuePair<string, string> kvp in PInvoke.ParseDN(distinguishedName))
            {
                components.Add(new DNComponent(kvp.Key, kvp.Value, true));
            }
        }

        public DistinguishedName(IEnumerable<DNComponent> dnComponents)
        {
            components = new List<DNComponent>(dnComponents);
            cachedDN = GetWholePath(",");
        }

        public bool Contains(DNComponent dnComponent)
        {
            return components.Contains(component);
        }

        public string GetDNSDomainName()
        {
            List<string> dcs = new List<string>();
            foreach (DNComponent dnc in components)
            {
                if(dnc.Type.Equals("DC", StringComparison.CurrentCultureIgnoreCase))
                {
                    dcs.Add(dnc.UnescapedValue);
                }
            }
            return string.Join(".", dcs.ToArray());
        }

        public string GetDomainDN()
        {
            List<string> dcs = new List<string>();
            foreach (DNComponent dnc in components)
            {
                if(dnc.Type.Equals("DC", StringComparison.CurrentCultureIgnoreCase))
                {
                    dcs.Add(dnc.WholeComponent);
                }
            }
            return string.Join(",", dcs.ToArray());
        }

        public string GetWholePath()
        {
            return GetWholePath(",");
        }

        public string GetWholePath(string separator)
        {
            List<string> parts = new List<string>();
            foreach (DNComponent component in components)
            {
                parts.Add(component.WholeComponent);
            }
            return string.Join(separator, parts.ToArray());
        }

        public DistinguishedName GetParent()
        {
            if(components.Count == 1)
            {
                return null;
            }
            List<DNComponent> tempList = new List<DNComponent>(components);
            tempList.RemoveAt(0);
            return new DistinguishedName(tempList);
        }

        public override bool Equals(object obj)
        {
            if(obj is DistinguishedName)
            {
                DistinguishedName objDN = (DistinguishedName)obj;
                if (this.Components.Length == objDN.Components.Length)
                {
                    for (int i = 0; i < this.Components.Length; i++)
                    {
                        if (!this.Components[i].Equals(objDN.Components[i]))
                        {
                            return false;
                        }
                    }
                    return true;
                }
                return false;
            }
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return cachedDN.GetHashCode();
        }
    }
}

I use a couple of utility classes based off of the Win32 methods DsGetRdnW, DsQuoteRdnValueW, and DsUnquoteRdnValueW:

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace UnmanagedCode
{
    public class PInvoke
    {
        #region Constants
        public const int ERROR_SUCCESS = 0;
        public const int ERROR_BUFFER_OVERFLOW = 111;
        #endregion Constants

        #region DN Parsing
        [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)]
        protected static extern int DsGetRdnW(
            ref IntPtr ppDN, 
            ref int pcDN, 
            out IntPtr ppKey, 
            out int pcKey, 
            out IntPtr ppVal, 
            out int pcVal
        );

        public static KeyValuePair<string, string> GetName(string distinguishedName)
        {
            IntPtr pDistinguishedName = Marshal.StringToHGlobalUni(distinguishedName);
            try
            {
                IntPtr pDN = pDistinguishedName, pKey, pVal;
                int cDN = distinguishedName.Length, cKey, cVal;

                int lastError = DsGetRdnW(ref pDN, ref cDN, out pKey, out cKey, out pVal, out cVal);

                if(lastError == ERROR_SUCCESS)
                {
                    string key, value;

                    if(cKey < 1)
                    {
                        key = string.Empty;
                    }
                    else
                    {
                        key = Marshal.PtrToStringUni(pKey, cKey);
                    }

                    if(cVal < 1)
                    {
                        value = string.Empty;
                    }
                    else
                    {
                        value = Marshal.PtrToStringUni(pVal, cVal);
                    }

                    return new KeyValuePair<string, string>(key, value);
                }
                else
                {
                    throw new Win32Exception(lastError);
                }
            }
            finally
            {
                Marshal.FreeHGlobal(pDistinguishedName);
            }
        }

        public static IEnumerable<KeyValuePair<string, string>> ParseDN(string distinguishedName)
        {
            List<KeyValuePair<string, string> components = new List<KeyValuePair<string, string>>();
            IntPtr pDistinguishedName = Marshal.StringToHGlobalUni(distinguishedName);
            try
            {
                IntPtr pDN = pDistinguishedName, pKey, pVal;
                int cDN = distinguishedName.Length, cKey, cVal;

                do
                {
                    int lastError = DsGetRdnW(ref pDN, ref cDN, out pKey, out cKey, out pVal, out cVal);

                    if(lastError = ERROR_SUCCESS)
                    {
                        string key, value;

                        if(cKey < 0)
                        {
                            key = null;
                        }
                        else if(cKey == 0)
                        {
                            key = string.Empty;
                        }
                        else
                        {
                            key = Marshal.PtrToStringUni(pKey, cKey);
                        }

                        if(cVal < 0)
                        {
                            value = null;
                        }
                        else if(cVal == 0)
                        {
                            value = string.Empty;
                        }
                        else
                        {
                            value = Marshal.PtrToStringUni(pVal, cVal);
                        }

                        components.Add(new KeyValuePair<string, string>(key, value));

                        pDN = (IntPtr)(pDN.ToInt64() + UnicodeEncoding.CharSize); //skip over comma
                        cDN--;
                    }
                    else
                    {
                        throw new Win32Exception(lastError);
                    }
                } while(cDN > 0);

                return components;
            }
            finally
            {
                Marshal.FreeHGlobal(pDistinguishedName);
            }
        }

        [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)]
        protected static extern int DsQuoteRdnValueW(
            int cUnquotedRdnValueLength,
            string psUnquotedRdnValue,
            ref int pcQuotedRdnValueLength,
            IntPtr psQuotedRdnValue
        );

        public static string QuoteRDN(string rdn)
        {
            if (rdn == null) return null;

            int initialLength = rdn.Length;
            int quotedLength = 0;
            IntPtr pQuotedRDN = IntPtr.Zero;

            int lastError = DsQuoteRdnValueW(initialLength, rdn, ref quotedLength, pQuotedRDN);

            switch (lastError)
            {
                case ERROR_SUCCESS:
                    {
                        return string.Empty;
                    }
                case ERROR_BUFFER_OVERFLOW:
                    {
                        break; //continue
                    }
                default:
                    {
                        throw new Win32Exception(lastError);
                    }
            }

            pQuotedRDN = Marshal.AllocHGlobal(quotedLength * UnicodeEncoding.CharSize);

            try
            {
                lastError = DsQuoteRdnValueW(initialLength, rdn, ref quotedLength, pQuotedRDN);

                switch(lastError)
                {
                    case ERROR_SUCCESS:
                        {
                            return Marshal.PtrToStringUni(pQuotedRDN, quotedLength);
                        }
                    default:
                        {
                            throw new Win32Exception(lastError);
                        }
                }
            }
            finally
            {
                if(pQuotedRDN != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pQuotedRDN);
                }
            }
        }


        [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)]
        protected static extern int DsUnquoteRdnValueW(
            int cQuotedRdnValueLength,
            string psQuotedRdnValue,
            ref int pcUnquotedRdnValueLength,
            IntPtr psUnquotedRdnValue
        );

        public static string UnquoteRDN(string rdn)
        {
            if (rdn == null) return null;

            int initialLength = rdn.Length;
            int unquotedLength = 0;
            IntPtr pUnquotedRDN = IntPtr.Zero;

            int lastError = DsUnquoteRdnValueW(initialLength, rdn, ref unquotedLength, pUnquotedRDN);

            switch (lastError)
            {
                case ERROR_SUCCESS:
                    {
                        return string.Empty;
                    }
                case ERROR_BUFFER_OVERFLOW:
                    {
                        break; //continue
                    }
                default:
                    {
                        throw new Win32Exception(lastError);
                    }
            }

            pUnquotedRDN = Marshal.AllocHGlobal(unquotedLength * UnicodeEncoding.CharSize);

            try
            {
                lastError = DsUnquoteRdnValueW(initialLength, rdn, ref unquotedLength, pUnquotedRDN);

                switch(lastError)
                {
                    case ERROR_SUCCESS:
                        {
                            return Marshal.PtrToStringUni(pUnquotedRDN, unquotedLength);
                        }
                    default:
                        {
                            throw new Win32Exception(lastError);
                        }
                }
            }
            finally
            {
                if(pUnquotedRDN != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUnquotedRDN);
                }
            }
        }
        #endregion DN Parsing
    }

    public class DNComponent
    {
        public string Type { get; protected set; }
        public string EscapedValue { get; protected set; }
        public string UnescapedValue { get; protected set; }
        public string WholeComponent { get; protected set; }

        public DNComponent(string component, bool isEscaped)
        {
            string[] tokens = component.Split(new char[] { '=' }, 2);
            setup(tokens[0], tokens[1], isEscaped);
        }

        public DNComponent(string key, string value, bool isEscaped)
        {
            setup(key, value, isEscaped);
        }

        private void setup(string key, string value, bool isEscaped)
        {
            Type = key;

            if(isEscaped)
            {
                EscapedValue = value;
                UnescapedValue = PInvoke.UnquoteRDN(value);
            }
            else
            {
                EscapedValue = PInvoke.QuoteRDN(value);
                UnescapedValue = value;
            }

            WholeComponent = Type + "=" + EscapedValue;
        }

        public override bool Equals(object obj)
        {
            if (obj is DNComponent)
            {
                DNComponent dnObj = (DNComponent)obj;
                return dnObj.WholeComponent.Equals(this.WholeComponent, StringComparison.CurrentCultureIgnoreCase);
            }
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return WholeComponent.GetHashCode();
        }
    }

    public class DistinguishedName
    {
        public DNComponent[] Components
        {
            get
            {
                return components.ToArray();
            }
        }

        private List<DNComponent> components;
        private string cachedDN;

        public DistinguishedName(string distinguishedName)
        {
            cachedDN = distinguishedName;
            components = new List<DNComponent>();
            foreach (KeyValuePair<string, string> kvp in PInvoke.ParseDN(distinguishedName))
            {
                components.Add(new DNComponent(kvp.Key, kvp.Value, true));
            }
        }

        public DistinguishedName(IEnumerable<DNComponent> dnComponents)
        {
            components = new List<DNComponent>(dnComponents);
            cachedDN = GetWholePath(",");
        }

        public bool Contains(DNComponent dnComponent)
        {
            return components.Contains(component);
        }

        public string GetDNSDomainName()
        {
            List<string> dcs = new List<string>();
            foreach (DNComponent dnc in components)
            {
                if(dnc.Type.Equals("DC", StringComparison.CurrentCultureIgnoreCase))
                {
                    dcs.Add(dnc.UnescapedValue);
                }
            }
            return string.Join(".", dcs.ToArray());
        }

        public string GetDomainDN()
        {
            List<string> dcs = new List<string>();
            foreach (DNComponent dnc in components)
            {
                if(dnc.Type.Equals("DC", StringComparison.CurrentCultureIgnoreCase))
                {
                    dcs.Add(dnc.WholeComponent);
                }
            }
            return string.Join(",", dcs.ToArray());
        }

        public string GetWholePath()
        {
            return GetWholePath(",");
        }

        public string GetWholePath(string separator)
        {
            List<string> parts = new List<string>();
            foreach (DNComponent component in components)
            {
                parts.Add(component.WholeComponent);
            }
            return string.Join(separator, parts.ToArray());
        }

        public DistinguishedName GetParent()
        {
            if(components.Count == 1)
            {
                return null;
            }
            List<DNComponent> tempList = new List<DNComponent>(components);
            tempList.RemoveAt(0);
            return new DistinguishedName(tempList);
        }

        public override bool Equals(object obj)
        {
            if(obj is DistinguishedName)
            {
                DistinguishedName objDN = (DistinguishedName)obj;
                if (this.Components.Length == objDN.Components.Length)
                {
                    for (int i = 0; i < this.Components.Length; i++)
                    {
                        if (!this.Components[i].Equals(objDN.Components[i]))
                        {
                            return false;
                        }
                    }
                    return true;
                }
                return false;
            }
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return cachedDN.GetHashCode();
        }
    }
}
伪心 2024-08-11 11:28:26

不,据我所知 - 即使在 Active Directory 的最新 .NET 3.5 命名空间中也没有。

您可以在目录本身中导航层次结构(转到父级等) - 但您需要通过DirectoryEntry 绑定到例如Active Directory。

然后还有 NameTranslate API,但这实际上更像是一个“将此名称更改为另一个名称”,例如从用户主体名称更改为相对 DN - 同样,它需要连接到 AD 中的 DirectoryEntry

我最感兴趣的是找到这样一个库,但到目前为止,我还没有听说过一个库 - 无论是在 .NET 还是任何其他语言中,真的。

回到我的“繁重”AD 编程时代,我有自己的一套 LDAP 路径操作例程(在 Delphi 中)——基本上只是字符串解析和处理。

马克

No, not to my knowledge - not even in the most recent .NET 3.5 namespace for Active Directory.

You can navigate the hierarchy (going to the parent etc.) in the directory itself - but you need to be bound to e.g. Active Directory by means of a DirectoryEntry.

And then there's the NameTranslate API, but that's really more of a "change this name to another name", e.g. change from user-principal name to relative DN - and again, it requires a connection to a DirectoryEntry in AD.

I would be most interested in finding such a library, but so far, I haven't heard about one - neither in .NET nor in any other language, really.

Back in my "heavy-duty" AD programming days, I had my own set of LDAP path manipulation routines (in Delphi) - basically just string parsing and handling.

Marc

走过海棠暮 2024-08-11 11:28:26

虽然 .NET 中没有 LDAP 路径解析器,但有 URI 解析器。对于那些需要简单解析“LDAP://domain/...”路径的人,您可以使用 System.Uri 类,然后您可以获得如下所示的一些详细信息:

var uri = new Uri(SomeDomainURI);
var scheme = uri.Scheme; // == "LDAP" or "LDAPS" usually
var domainHost = uri.Host;
var path = uri.AbsolutePath.TrimStart('/');

如果您使用 此 DN 解析器 您还可以执行以下操作解析路径:

var dn = new DN(uri.AbsolutePath.TrimStart('/'));

虽然我同意 .NET 现在应该已经有了这个(遗憾!),但这至少是满足我需求的一个不错的解决方案,尽管并不完美,而且我怀疑它对每个人来说都足够强大。

While there is no LDAP path parser in .NET, there is a URI parser. For those who need to simply parse "LDAP://domain/..." paths you can use the System.Uri class, then you can get some details like the following:

var uri = new Uri(SomeDomainURI);
var scheme = uri.Scheme; // == "LDAP" or "LDAPS" usually
var domainHost = uri.Host;
var path = uri.AbsolutePath.TrimStart('/');

If you use this DN parser you can also do the following instead to parse the path:

var dn = new DN(uri.AbsolutePath.TrimStart('/'));

While I agree that .NET should have had this by now (shame!), this was at least an ok work around for my needs, though not perfect, and I doubt it will be robust enough for everyone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文