How to best implement custom search on a Membership provider
-
03-07-2019 - |
Question
Out of the box, System.Web.Security.Membership implements a couple of search methods:
- FindUsersByEmail
- FindUsersByName
I'm using the WSAT project from CodePlex to administer my Membership database. The tool implements extra profile properties in a ProfileCommon class.
Let's say I have a property called Firm in the user's profile.
I need to implement a custom search method to search on the Firm property, and I would like to do this all in code. Don't wanna write a stored procedure (since all the profile properties are stored in 1 database column in the WSAT tool).
Something like this obviously isn't the right way to do it, but here it is to just demonstrate accessing the user's profile properties:
private MembershipUserCollection SearchByFirm(string firmName, MembershipUserCollection allRegisteredUsers)
{
MembershipUserCollection searchResults = new MembershipUserCollection();
foreach (MembershipUser user in allRegisteredUsers)
{
ProfileCommon profile = Profile.GetProfile(user.UserName);
if (profile.Firm.ToLowerInvariant().Contains(firmName.ToLowerInvariant()))
{
searchResults.Add(user);
}
}
return searchResults;
}
Can I turn this into some LINQ goodness?
Solution 2
Got some help from a colleague who's good with linq. The challenge here is that MembershipUserCollection doesn't implement IEnumerable< T > (!).
List<MembershipUser> searchResults = allUsers.Where(user =>
Profile.GetProfile(user.UserName).Firm.ToLowerInvariant()
.Contains(firmName.ToLowerInvariant())).ToList();
in this case allUsers is a List which I had to populate with the items in the Membership.GetAllUsers() collection.
OTHER TIPS
Well can't you just cast it?
IEnumerable<MembershipUser> searchResults = Membership.GetAllUsers().Cast<MembershipUser>();
Hope this helps you guys
Just for the record I created this extension method which I think it kinda works:
namespace WebDibaelsaMVC.Utils.MembershipUserCollectionExtensions
{
public static class MembershipUserCollectionExtensions
{
public static IEnumerable<MembershipUser> Where(this MembershipUserCollection userCollection,Func<MembershipUser,bool> func)
{
foreach (MembershipUser membershipUser in userCollection)
{
if (func(membershipUser))
yield return membershipUser;
}
}
}
}
It also converts the MembershipUserCollection
to an IEnumerable<MembershipUser>
so all other LINQ methods work afterwards.
There is no built in function provided by microsoft. Here is the example of search membership user with UserName and Email Address
Example:
Just Copy below function and implement it - Done...
Public List<MembershipUser> SearchMembershipUser(string strUserName, String strEmail)
{
IEnumerable<MembershipUser> MUser;
if ((!string.IsNullOrEmpty(strUserName) || !string.IsNullOrEmpty(strEmail)))
{
if (!string.IsNullOrEmpty(strUserName) && !string.IsNullOrEmpty(strEmail))
{
MUser = Membership.GetAllUsers().Cast<MembershipUser>()
.Where(x => x.UserName != CurrentUser && x.UserName == strUserName && x.Email == strEmail);
}
else if (!string.IsNullOrEmpty(strUserName))
{
MUser = Membership.GetAllUsers().Cast<MembershipUser>()
.Where(x => x.UserName != CurrentUser && x.UserName == strUserName);
}
else
{
MUser = Membership.GetAllUsers().Cast<MembershipUser>()
.Where(x => x.UserName != CurrentUser && x.Email == strEmail);
}
}
else
{
MUser = Membership.GetAllUsers().Cast<MembershipUser>().Where(x => x.UserName != CurrentUser);
}
return MUser.OrderBy(x => x.UserName).ToList();
}