I'm using the default SqlMembershipProvider, but I've created a custom MembershipUser class (SoeMembershipUser) because I needed a "DisplayName" property. All the DisplayName does is look at the UserName and format it differently开发者_StackOverflow社区.
When I try to cast a MembershipUser to a SoeMembershipUser user I get an InvalidCastException. Exact error is: "Unable to cast object of type 'System.Web.Security.MembershipUser' to type 'Soe.Tracker.SoeMembershipUser'."
Here is the code that fails:
SoeMembershipUser user = (SoeMembershipUser)Membership.GetUser(username); // invalid cast
I have also tried casting later like so:
MembershipUser user = Membershipship.GetUser(username); // ok
...
string displayName = ((SoeMembershipUser)user).DisplayName; // invalid cast
Here is the SoeMembershipUser class: NOTE: I left off the constructors at first, but added them in later when I started having problems. Adding them made no difference.
public class SoeMembershipUser : MembershipUser
{
public SoeMembershipUser()
: base()
{
}
public SoeMembershipUser(string providerName, string name,
Object providerUserKey, string email, string passwordQuestion,
string comment, bool isApproved, bool isLockedOut,
DateTime creationDate, DateTime lastLoginDate,
DateTime lastActivityDate, DateTime lastPasswordChangedDate,
DateTime lastLockoutDate)
: base(providerName, name, providerUserKey, email,
passwordQuestion, comment, isApproved, isLockedOut,
creationDate, lastLoginDate, lastActivityDate,
lastPasswordChangedDate, lastLockoutDate)
{
}
public virtual string DisplayName
{
get
{
if (UserName.Contains("@"))
return UserName.Substring(0, UserName.IndexOf("@"));
return UserName;
}
}
}
Any idea why this cast is invalid? Am I just overlooking something simple?
You are trying to downcast from a base to a derived class (aka a narrowing conversion, as from an Animal to a Dog -- but not every animal is a dog). Create an extension method, ToMembershipUser, that will do the conversion since you know how it should proceed and the compiler doesn't.
The problem is that you are using the default SqlMembershipProvider. You will have to create a custom MembershipProvider.
You can probably get by with just extending the SqlMembershipProvider on the GetUser methods.
public class SoeMembershipProvider : SqlMembershipProvider
{
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
var sqlMembershipUser = base.GetUser(providerUserKey, userIsOnline);
return new SoeMembershipUser(sqlMembershipUser);
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
var sqlMembershipUser = base.GetUser(username, userIsOnline);
return new SoeMembershipUser(sqlMembershipUser);
}
}
精彩评论