【问题标题】:Cannot cast MembershipUser to custom class (ASP.NET)无法将 MembershipUser 转换为自定义类 (ASP.NET)
【发布时间】:2010-10-15 19:58:09
【问题描述】:

我正在使用默认的 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;
        }
    }
}

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

【问题讨论】:

  • 你能发布实际的无效转换错误消息吗?
  • 我在上面添加了确切的错误消息。堆栈跟踪没有显示任何异常。

标签: asp.net casting asp.net-membership membership membershipuser


【解决方案1】:

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

【讨论】:

  • 作为扩展方法的替代方法,您可以使用 C# 'explicit' 关键字,如下所示:msdn.microsoft.com/en-us/library/xhbhezf4(v=VS.100).aspx
  • 关于“显式”:似乎我需要将显式运算符添加到 MembershipUser 类本身,以便它在我的情况下有用(除非我读错了文档)。
  • 是的,你是对的——显式运算符在这种情况下不起作用。我的错。只需使用独立功能或扩展方法即可。任何一个都应该工作。
  • 看来我工作太努力了,无法得到一个简单的结果,但我想我最终不得不这样做。这令人沮丧,因为在我的情况下,这些类型是“可交换的”(如果有机会运行,它们永远不会发生冲突)。我确实很欣赏这个类比,并且理解为什么我会得到错误。 CS 101...
【解决方案2】:

问题在于您使用的是默认的 SqlMembershipProvider。您必须创建一个custom 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);
    }
}

【讨论】:

  • +1 我同意这可能会解决我的问题,但它不像我想要的那样可扩展,因为我希望能够为现有系统交换成员资格提供程序。由于 .NET 不允许多重继承,即使我从 MembershipProvider 而不是 SqlMembershipProvider 继承,这也会导致问题。
  • @Rick 我看到你接受了另一个答案,所以我假设你有一个计划。祝你好运。
猜你喜欢
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
相关资源
最近更新 更多