0

我正在使用默认的 SqlMembershipProvider,但我创建了一个自定义 MembershipUser 类 (SoeMembershipUser),因为我需要一个“DisplayName”属性。DisplayName 所做的只是查看 UserName 并以不同的方式对其进行格式化。

当我尝试将 MembershipUser 强制转换为 SoeMembershipUser 用户时,我得到一个 InvalidCastException。确切的错误是:“无法将'System.Web.Security.MembershipUser'类型的对象转换为'Soe.Tracker.SoeMembershipUser'。”

这是失败的代码:

SoeMembershipUser user = (SoeMembershipUser)Membership.GetUser(username); // invalid cast

我也尝试过像这样稍后进行铸造:

MembershipUser user = Membershipship.GetUser(username); // ok
...
string displayName = ((SoeMembershipUser)user).DisplayName; // invalid cast

这是 SoeMembershipUser 类: 注意:我一开始没有使用构造函数,但后来当我开始遇到问题时添加了它们。添加它们没有任何区别。

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;
        }
    }
}

知道为什么这个演员表无效吗?我只是忽略了一些简单的事情吗?

4

2 回答 2

2

您正试图从基类向下转换为派生类(也称为缩小转换,如从动物到狗——但并非每只动物都是狗)。创建一个扩展方法 ToMembershipUser,它将执行转换,因为您知道它应该如何进行而编译器不知道。

于 2010-10-15T20:06:16.480 回答
2

问题是您使用的是默认的 SqlMembershipProvider。您必须创建一个自定义 MembershipProvider

您可能只需在 GetUser 方法上扩展 SqlMembershipProvider 即可。

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);
    }
}
于 2010-10-15T20:07:18.457 回答