asp.net extending IPrincipal
Asked Answered
D

4

8

I would like to extend IPrincipal in asp.net to allow me to get the usertype that I will define. I would like to make it possible to do this in a controller

string type = User.UserType 

then in my extension method i will have a method like

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

}

how can I do this? is it possible? Thanks!

Disc answered 9/7, 2010 at 16:14 Comment(2)
You don't extend an interface, you implement it.Tudela
Or, rather, it's possible to extend it, but that's something else. That would be creating a new interface that is a superset of the base.Tudela
K
11

You can make an extension method:

public static string UserType(this IPrincipal principal) {
    // do some database access 
    return something;
}
Kathrinkathrine answered 9/7, 2010 at 16:24 Comment(3)
That would be clever, but risky. The "return something" part would actually have to downcast it to his implementation and call some property. This would fail if executed on any other IPrincpal implementation.Tudela
what does the class need to look like in which this extension method is found?Disc
It needs to be a static class.Kathrinkathrine
F
3

Sure. Make your class implements IPrincipal:

public class MyPrinciple : IPrincipal {
    // do whatever
}

Extension method:

public static string UserType(this MyPrinciple principle) {
    // do something
}
Fuchsia answered 9/7, 2010 at 16:22 Comment(1)
Same problem as SLaks' answer: the "do something" is going to involve downcasting, which can fail.Tudela
P
2

Here is an example custom class that implements IPrincipal. This class includes a few extra methods to check for role affiliation but shows a property named UserType per your requirements.

  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!

Palladous answered 9/7, 2010 at 16:22 Comment(1)
Right, except that they couldn't call UserType given a reference to IPrincipal.Tudela
T
2

Basically, no. You can implement IPrincipal with a class such as MyPrincipal, and that class can have a UserType property, but you'd have to access the instance through a reference of its own type in order to reach it, not through the interface reference.

edit

An extension method could work, but only if you're absolutely certain you'll never call it on something that implements IPrincipal but isn't an instance of your own class.

Tudela answered 9/7, 2010 at 16:22 Comment(2)
Thank you. I will think about the the chances of IPrincipal being implemented somewhere else. I am not sure if it ever will on my application. I am not sure what scenarios would cause this. But if so the implementing it would also work for me. Thank you sir!Disc
@twal: Often, the framework hands you an IPrincipal whose implementation is some class from that framework. So long as you're certain this won't happen, an extension method will fill your needs.Tudela

© 2022 - 2024 — McMap. All rights reserved.