2010-07-09 11 views
7

Me gustaría extender IPrincipal en asp.net para permitirme obtener el tipo de usuario que definiré. Me gustaría que sea posible hacer esto en un controladorasp.net extendiendo IPrincipal

string type = User.UserType 

entonces en mi método de extensión voy a tener un método como

public string UserType() 
{ 
    // do some database access 
    return userType 

} 

cómo puedo hacer esto? ¿Es posible? Gracias!

+0

Usted no se extienden a una interfaz, a ponerla en práctica. –

+0

O, mejor dicho, es posible ampliarlo, pero eso es otra cosa. Eso crearía una nueva interfaz que es un superconjunto de la base. –

Respuesta

10

Puede realizar un método de extensión:

public static string UserType(this IPrincipal principal) { 
    // do some database access 
    return something; 
} 
+0

Eso sería inteligente, pero arriesgado. La parte "devolver algo" en realidad tendría que bajarla a su implementación y llamar a alguna propiedad. Esto fallaría si se ejecuta en cualquier otra implementación de IPrincpal. –

+0

¿cómo debe verse la clase en la que se encuentra este método de extensión? – twal

+1

Tiene que ser una 'clase estática'. – SLaks

2

Aquí hay un ejemplo de clase personalizada que implementa IPrincipal. Esta clase incluye algunos métodos adicionales para verificar la afiliación de roles, pero muestra una propiedad llamada UserType según sus requisitos.

public class UserPrincipal : IPrincipal 
    { 
    private IIdentity _identity; 
    private string[] _roles; 

    private string _usertype = string.Empty; 


    public UserPrincipal(IIdentity identity, string[] roles) 
    { 
     _identity = identity; 
     _roles = new string[roles.Length]; 
     roles.CopyTo(_roles, 0); 
     Array.Sort(_roles); 
    } 

    public IIdentity Identity 
    { 
     get 
     { 
     return _identity; 
     } 
    } 

    public bool IsInRole(string role) 
    { 
     return Array.BinarySearch(_roles, role) >= 0 ? true : false; 
    } 

    public bool IsInAllRoles(params string[] roles) 
    { 
     foreach (string searchrole in roles) 
     { 
     if (Array.BinarySearch(_roles, searchrole) < 0) 
     { 
      return false; 
     } 
     } 
     return true; 
    } 

    public bool IsInAnyRoles(params string[] roles) 
    { 
     foreach (string searchrole in roles) 
     { 
     if (Array.BinarySearch(_roles, searchrole) > 0) 
     { 
      return true; 
     } 
     } 
     return false; 
    } 

    public string UserType 
    { 
     get 
     { 
     return _usertype; 
     } 
     set 
     { 
     _usertype = value; 
     } 
    } 

    } 

Enjoy!

+0

Correcto, excepto que no pudieron llamar a UserType con una referencia a IPrincipal. –

2

Básicamente, no. Puede implementar IPrincipal con una clase como MyPrincipal, y esa clase puede tener una propiedad UserType, pero tendría que acceder a la instancia a través de una referencia de su propio tipo para acceder a ella, no a través de la referencia de la interfaz.

editar forma de

Una extensión podría funcionar, pero sólo si está absolutamente seguro de que nunca va a llamar en algo que implementa IPrincipal pero no es una instancia de su propia clase.

+0

Gracias. Pensaré sobre las posibilidades de que IPrincipal se implemente en otro lugar. No estoy seguro si alguna vez lo hará en mi solicitud. No estoy seguro de qué escenarios causarían esto. Pero si es así, la implementación también me funcionaría. ¡Gracias Señor! – twal

+0

@twal: a menudo, el marco le da un IPrincipal cuya implementación es una clase de ese marco. Siempre que esté seguro de que esto no sucederá, un método de extensión cubrirá sus necesidades. –

+0

Gracias Steven! – twal

3

Sure. Haga su clase implementa IPrincipal:

public class MyPrinciple : IPrincipal { 
    // do whatever 
} 

método de extensión:

public static string UserType(this MyPrinciple principle) { 
    // do something 
} 
+0

El mismo problema que la respuesta de SLaks: el "hacer algo" va a involucrar downcasting, que puede fallar. –