カスタムクラスを使用して、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:
要約:現在設定されていない場合は値を設定できますが、既存の値を上書きしたい場合はエラーが発生します。