I found a work around, by setting the value to null first it no-longer throws the exception.
using (var update = ExamplePrincipal.FindByIdentity(context, "example"))
{
update.BlobData = null;
update.Save();
update.BlobData = new byte[] { 0x12, 0x34, 0x56, 0x67 };
update.Save(); //No longer fails with method 1.
}
I am leaving the question open for a bit to see if anyone else can answer if there is a "proper" way to do this.
Found a 2nd work around that does not require forcing a save.
[DirectoryProperty("vwBlobData")]
public byte[] BlobData
{
get
{
if (ExtensionGet("vwBlobData").Length != 1)
return null;
return (byte[])ExtensionGet("vwBlobData")[0];
}
set
{
((DirectoryEntry)this.GetUnderlyingObject())
.Properties["vwBlobData"].Value = value;
}
}
By casting directly to the underlying object you can set the value directly. I checked using ILSpy and disposing the AccountManagement wrapper disposes the underlying object, so no Dispose()
is required for the GetUnderlyingObject()
call.
BEST SOLUTION
I found out the 2nd work around required the object to be persisted to work, so I made a best of both worlds approach. This works when you have not yet persisted the object, when the object is null, and when the object has a value already.
[DirectoryProperty("vwBlobData")]
public byte[] BlobData
{
get
{
if (ExtensionGet("vwBlobData").Length != 1)
return null;
return (byte[])ExtensionGet("vwBlobData")[0];
}
set
{
if(ExtensionGet("vwBlobData").Length == 0)
this.ExtensionSet("vwBlobData", data);
else
((DirectoryEntry)this.GetUnderlyingObject())
.Properties["vwBlobData"].Value = data;
}
}