문제

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.

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);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top