カスタムクラスを使用して、ActiveDirectoryでカスタムスキーマを公開しています。私はバイナリブロブを保存しています。プロジェクトの要件に従って、このデータはADに保存する必要があり、外部ストアを使用することはできません(可能であれば)。
ユーザーを作成すると、blobが正常に保存されます。また、blobを正常に取得して、すべてのデータを取得することもできます。問題は、値を更新する必要があり、エラーが発生する場合です
小さなサンプルプログラム:
using System;
using System.DirectoryServices.AccountManagement;
namespace SandboxConsole40
{
class Program
{
static void Main(string[] args)
{
using(var context = new PrincipalContext(ContextType.Domain))
{
using (var clear = ExamplePrincipal.FindByIdentity(context, "example"))
{
if (clear != null)
clear.Delete();
}
using (var create = new ExamplePrincipal(context, "example", "Password1", false))
{
create.Save();
}
using (var set = ExamplePrincipal.FindByIdentity(context, "example"))
{
set.BlobData = new byte[] { 0xDE, 0xAD, 0xBE, 0xEF }; //This fails with method 2.
set.Save();
}
using (var lookup = ExamplePrincipal.FindByIdentity(context, "example"))
{
Console.WriteLine(BitConverter.ToString(lookup.BlobData));
}
using (var update = ExamplePrincipal.FindByIdentity(context, "example"))
{
update.BlobData = new byte[] { 0x12, 0x34, 0x56, 0x67 };
update.Save(); //This save fails with method 1.
}
}
Console.WriteLine("Done");
Console.ReadLine();
}
[DirectoryObjectClass("user")]
[DirectoryRdnPrefix("CN")]
class ExamplePrincipal : UserPrincipal
{
public ExamplePrincipal(PrincipalContext context) : base(context) { }
public ExamplePrincipal(PrincipalContext context, string samAccountName, string password, bool enabled)
: base(context, samAccountName, password, enabled) { }
public static new ExamplePrincipal FindByIdentity(PrincipalContext context, string identityValue)
{
return (ExamplePrincipal)FindByIdentityWithType(context, typeof(ExamplePrincipal), identityValue);
}
[DirectoryProperty("vwBlobData")]
public byte[] BlobData
{
get
{
if (ExtensionGet("vwBlobData").Length != 1)
return null;
return (byte[])ExtensionGet("vwBlobData")[0];
}
set
{
//method 1
this.ExtensionSet("vwBlobData", value );
//method 2
//this.ExtensionSet("vwBlobData", new object[] { value});
}
}
}
}
}
メソッド1を使用すると、update.Save()操作で次の例外が発生します
System.DirectoryServices.AccountManagement.PrincipalOperationExceptionが処理されませんでした
HResult = -2146233087
メッセージ=指定されたディレクトリサービスの属性または値はすでに存在します。
Source = System.DirectoryServices.AccountManagement
ErrorCode = -2147016691
スタックトレース:
//をちょきちょきと切る
InnerException:System.DirectoryServices.DirectoryServicesCOMException
HResult = -2147016691
メッセージ=指定されたディレクトリサービスの属性または値はすでに存在します。
Source = System.DirectoryServices
ErrorCode = -2147016691
ExtendedError = 8321
ExtendedErrorMessage = 00002081:AtrErr:DSID-030F154F、#1:
0:00002081:DSID-030F154F、問題1006(ATT_OR_VALUE_EXISTS)、データ0、Att 82818fec(vwBlobData)
スタックトレース:
//をちょきちょきと切る
InnerException:
this.ExtensionSetメソッド2を使用すると、呼び出しからの呼び出しから例外が発生しset.BlobDataます。
System.ArgumentExceptionが処理されませんでした
HResult =-2147024809
Message =要素が別のコレクションであるコレクションは、ExtensionClassesでは設定できません。
Source = System.DirectoryServices.AccountManagement
スタックトレース:
//をちょきちょきと切る
InnerException:
要約:現在設定されていない場合は値を設定できますが、既存の値を上書きしたい場合はエラーが発生します。