I need to retrieve an extended attribute from Active Directory, for which there is a private method in the ComputerPrincipal
class. I understand I can only access the private method through a derived class, so I've derived a class ComputerPrincipalEx
from the base class. I've then created (defined?) a method in the derived class which calls the private method in the base class. This part seems OK.
The problem comes when I try to use a (public) method of the base class to assign a value to a variable with the type of the derived class. Here's the code, then I'll try to explain more:
The derived class:
public class ComputerPrincipalEx : ComputerPrincipal
{
public ComputerPrincipalEx(PrincipalContext context) : base(context) { }
public ComputerPrincipalEx(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled) { }
public string ExtensionGet(string extendedattribute)
{
return (string) base.ExtensionGet(extendedattribute)[0];
}
}
The problem code, which itself is a method of another class I've created:
public string GetExtendedAttribute(string attributeName) { PrincipalContext ctx = new PrincipalContext(ContextType.Domain); ComputerPrincipalEx cp = new ComputerPrincipalEx(ctx); cp = ComputerPrincipalEx.FindByIdentity(ctx, Name); return cp.ExtensionGet(attributeName); }
ExtensionGet
is the private method of the base class that I need to expose, and I think I have this correct because once I create an object of type ComputerPrincipalEx
, I can access ExtensionGet
, which is otherwise inaccessible.
The problem is the type conversion in this line: cp = ComputerPrincipalEx.FindByIdentity(ctx, Name);
cp
is defined as ComputerPrincipalEx;
ComputerPrincipalEx.FindByIdentity
references the base ComputerPrincipal.FindByIdentity
method, and returns a ComputerPrincipal
. The compiler balks about an implicit conversion between types. Casting ComputerPrincipal
to ComputerPrincipalEx
satisfies the compiler but the app crashes at runtime because it can't perform the conversion.
Now, I pretty much understand all of that, but I'm assuming there has to be some way to call a method from the base class and return valid data to an object of the derived class' type, and that's what I'm hoping to find out how to do.
I was able to figure this out based on information I found here and here .
In the derived ComputerPrincipalEx
class, I needed to hide the base class' FindByIdentity
method and redefine it to call FindByIdentityWithType
. This let me cast the return type to be ComputerPrincipalEx
and thus access the ExtensionGet
method. (Hopefully I'm explaining that properly; this is still very new to me.)
For this to work however, the below lines needed to be added as well. Otherwise the compiler threw an error that ComputerPrincipalEx
was not a valid object type to search with.
[DirectoryObjectClass("computer")]
[DirectoryRdnPrefix("CN")]
Here's the relevant excerpt from the ComputerPrincipalEx
class: (Yes, I know the try/catch block needs some work.)
[DirectoryObjectClass("computer")]
[DirectoryRdnPrefix("CN")]
public class ComputerPrincipalEx : ComputerPrincipal
{
public ComputerPrincipalEx(PrincipalContext context) : base(context) { }
public ComputerPrincipalEx(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled) { }
new public string ExtensionGet(string extendedattribute)
{
try
{
if (base.ExtensionGet(extendedattribute).Length != 1)
{
return null;
}
else
{
return (string)base.ExtensionGet(extendedattribute)[0];
}
}
catch (Exception ex)
{
// This should be broken down to individual exceptions
string message = string.Format("Exception occurred while retrieving extended attribute {0}. \r\nThe following error occurred:\r\n {1}", extendedattribute, ex);
MessageBox.Show(message);
Application.Exit();
return null;
}
}
public static new ComputerPrincipalEx FindByIdentity(PrincipalContext ctx, string identityValue)
{
return (ComputerPrincipalEx)FindByIdentityWithType(ctx, typeof(ComputerPrincipalEx), identityValue);
}
}
And the revised GetExtendedAttribute
call:
public string GetExtendedAttribute(string attributeName)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
var cp = ComputerPrincipalEx.FindByIdentity(ctx, Name);
return cp.ExtensionGet(attributeName);
}
Thanks all for the help. Hopefully this helps someone else who runs into the same problem.
Change to this:
public string GetExtendedAttribute(string attributeName)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
var cp = ComputerPrincipalEx.FindByIdentity(ctx, Name);
return cp.ExtensionGet(attributeName);
}
在我的印象中,您需要ComputerPrincipalEx中的一个构造函数(或静态方法),该构造函数是从基类的实例创建的。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.