我正在嘗試編寫實用程序方法來更新C#中的AD屬性(現在只是單值字符串屬性)。這是一個獨立的實用程序,不依賴於IIS。這種方法將用於從我們的HR系統加載數據到我們的AD中。如何防止DirectoryOperationException - 服務器無法處理目錄請求
我能夠使用System.DirectoryServices.Protocols高效地讀取對象和屬性。但是當我調用ModifyRequest方法時,我得到一個DirectoryOperationException,並顯示消息「服務器無法處理目錄請求」。
基於另一個堆棧溢出問題: .Net's Directory Services throws a strange exception
我嘗試使用端口636進行SSL LDAP,但它不會改變的行爲。
我沒有使用IIS並且在.NET 4.5上,因此Microsoft .NET/IIS補丁不適用。
在此搜索結果一直沒有結果。
如果知道你爲什麼會出現這個錯誤,以及如何解決它,我將非常感激。
下面的代碼..請假設Conn包含來自封閉實用程序類的有效和經過身份驗證的LDAP連接 - 如果需要,我可以提供封閉實用程序類的完整源代碼。
唯一的例外發生在SendRequest
線ModifyStringAttributeValues
:
using System;
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using System.Net;
namespace MyOrganization.Common.Ldap
{
public class LdapSession
{
public bool UseKerberos { set; get; }
public String Host { set; get; }
public String UserId { set; get; }
public String Password { set; get; }
public String Tag { set; get; }
public int Port { set; get; }
public const int DefaultLdapPort = 389;
protected LdapConnection Conn;
public void EstablishV2()
{
}
public void Establish()
{
var effectivePort = Port == 0 ? DefaultLdapPort : Port;
Console.WriteLine("EffectivePort={0}", effectivePort);
var identifier = new LdapDirectoryIdentifier(Host, effectivePort);
if (UseKerberos)
{
Conn = new LdapConnection(identifier)
{
AuthType = AuthType.Kerberos,
Timeout = new TimeSpan(0, 10, 0, 0),
SessionOptions =
{
ProtocolVersion = 3,
VerifyServerCertificate =
new VerifyServerCertificateCallback((con, cer) => true),
SecureSocketLayer = true
}
};
}
else
{
Conn = new LdapConnection(identifier)
{
AuthType = AuthType.Basic,
Timeout = new TimeSpan(0, 10, 0, 0)
};
// Console.WriteLine("LPA: Binding with {0}, {1}", UserId, Password); // QUARTZ
Conn.Bind(new NetworkCredential(UserId, Password));
}
}
public IEnumerable<SearchResultEntry> Search(string cx, string filter, SearchScope searchScope, params string[] attrib)
{
var s = new SearchRequest(cx, filter, searchScope, attrib)
{
SizeLimit = 0,
TimeLimit = new TimeSpan(1, 0, 0) // One hour, zero minutes, zero seconds
};
var raw = Conn.SendRequest(s);
if (raw == null)
{
throw new Exception("null response");
}
var r = raw as SearchResponse;
if (r != null)
{
// Console.WriteLine(Tag + "Search response entries: {0}", r.Entries.Count); // QUARTZ
foreach (SearchResultEntry e in r.Entries)
{
yield return e;
}
}
else
{
// Console.WriteLine(Tag + "Search response was null"); // QUARTZ
}
yield break;
}
public ResultCode ModifyStringAttributeValues(string dn, IDictionary<string, string> modifications)
{
// declare the request and response objects here
// they are used in two blocks
ModifyRequest modRequest;
ModifyResponse modResponse;
try
{
// initialize the modRequest object
modRequest =
new ModifyRequest(dn);
modRequest.Controls.Add(new PermissiveModifyControl());
var mods = new DirectoryAttributeModification[modifications.Count];
int z = 0;
foreach (var pair in modifications)
{
var mod = new DirectoryAttributeModification();
mod.Operation = DirectoryAttributeOperation.Replace;
mod.Name = pair.Key;
mod.Add(pair.Value);
mods[z] = mod;
z += 1;
}
// cast the returned directory response into a ModifyResponse type
// named modResponse
modResponse =
(ModifyResponse)Conn.SendRequest(modRequest);
return modResponse.ResultCode;
}
catch (Exception e)
{
Console.WriteLine("\nUnexpected exception occured:\n\t{0}: {1}",
e.GetType().Name, e.Message);
return ResultCode.Unavailable;
}
}
}
}
我知道代碼是有點麻煩,而且充滿了詭異的意見 - 這是剪切,粘貼和示例代碼在微軟的網站修改而我得到它的工作。
我也想知道爲什麼你需要PermissiveModifyControl。你沒有嘗試過嗎? http://stackoverflow.com/q/3450732/1236044 – jbl
你有沒有找到你的問題的答案?(完成一個C# - redhat LDAP DS,我可能會有一個AD LDAP項目進來,所以我正在收集一些信息;-)有些人建議在AD服務器上儘可能提高日誌級別爲「服務器無法處理目錄請求「似乎是一個普通的AD錯誤 – jbl