3

If this sounds confusing it's because I'm al little confused on it myself. Basically I have an application (originally written by someone else but never finished) that needs to perform various actions on spuser objects. The catch is that the input being used to find the user can be any of several types of identification. The method requiring this may have user information in the form of user Id, login name, email address, account name, etc. The method needs to detect what kind of information it is and use an appropriate means for retrieving the user account.

My first (and only) idea was to use exception handling to take the value and "brute force" it by trying a series of gets until one of them finally sticks. As in,

try
{
  SPUserCollection myUserCollection = myWeb.Users;
  SPUser myUser = myUserCollection.GetByEmail(value);
}
catch
{
  try
  {
    SPUserCollection myUserCollection = myWeb.Users;
    SPUser myUser = myUserCollection.GetById(value);
  }
  catch
  {
    ...and so on

Of course this is horribly messy and I"m not even sure it will work. Is there a better way? I really don't want to scrap the whole thing and start over because it would take a huge amount of time and experience that I don't have yet, so I really want to hack something together that will do the job for the moment until I know how to write something better.

Thanks in advance for any help you can provide!

1
  • Can you check what is stored in value? If value.Contains("@"), then I'm sure it's safe to call it an email, and then you can use GetByEmail. If it can be parsed into an int, then it's likely to be the ID.
    – wjervis
    Jan 15, 2014 at 19:03

2 Answers 2

2

It can be daunting when taking over someone else's code, and you want to be the least invasive possible. In this case, you may need to make your incision a little deeper! Ideally, via your application design you should know where value is coming from. If you don't, see if you can alter the collection of value so you can control its data type (email or Id). Once you do know the type of data in format, you can create a method for each type value, and call the appropriate one:

public SPUser GetUserByEmail(SPWeb myWeb, string email)
{
  SPUser myUser = myWeb.Users.GetByEmail(email);
  return myUser;
}

public SPUser GetUserById(SPWeb myWeb, int userId)
{
  SPUser myUser = myWeb.Users.GetById(userId);
  return myUser;
}
1

You can provide an Extension Method which can take care of any type of "value" as parameter like this:

public static SPUser TryGetByAnything(this SPUserCollection coll, string nameOrId, bool ensureIfNotExist)
{
    SPUser result = null;
    if (nameOrId.IsNumeric())
    {
        int id = int.Parse(nameOrId);
        GeneralHelpers.Try(() => result = coll.GetByID(id));
    }
    else
    {
        bool allUnsafe = coll.Web.AllowUnsafeUpdates;
        coll.Web.AllowUnsafeUpdates = true;
        GeneralHelpers.Try(() => result = coll[nameOrId]);
        if (result == null) result = coll.OfType<SPUser>().Where(c => c.Name.Equals(nameOrId, StringComparison.OrdinalIgnoreCase) || c.LoginName.Equals(nameOrId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
        if (result == null && ensureIfNotExist) GeneralHelpers.Try(() => result = coll.Web.EnsureUser(nameOrId));
        coll.Web.AllowUnsafeUpdates = allUnsafe;
    }
    return result;
}  

There are some methods i used in this method:

public static System.Boolean IsNumeric(this System.Object Expression)
{
    if (Expression == null || Expression is DateTime)
        return false;

    if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
        return true;

    try
    {
        if (Expression is string)
            Double.Parse(Expression as string);
        else
            Double.Parse(Expression.ToString());
        return true;
    }
    catch { }
    return false;
}

public static void Try(Action v)
{
    try { v(); }
    catch { }
}  

"IsNumeric" method is Extension so you must put it in a static class but "Try" is not.
You can add support for other types of "value".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.