无法将“System.String”类型的对象强制转换为“System.Web.Security.MembershipUser”类型

时间:2010-03-10 14:56:46

标签: .net casting

我正在尝试获取用户名列表并将它们绑定到DropDownList,我必须错过一个技巧,因为我似乎无法将其转换为正确的类型。代码如下,标题是我收到的错误信息。

编辑 - Quser继承自MembershipUser

UserRepository userRepository = new UserRepository();
// retrieve custom user objects 
IEnumerable<QUser> Users = userRepository.GetAllUsers(); 
// just get usernames only
IEnumerable<string> userList = (from u in Users select  u.UserName); 

// set usernames to data source for a DropDownList
Username.DataSource = userList.ToArray(); // Cast error occurs here
Username.DataBind();

我也尝试使用cast方法强制转换IEnumerable,但没有运气:

userList.Cast<string>().ToArray();

编辑:

QUser Class

public class QUser : MembershipUser 
    {
        public QUser(){}

        public QUser(MembershipUser user): 
            base(user.ProviderName, user.UserName, user.ProviderUserKey, user.Email, 
            user.PasswordQuestion, user.Comment, user.IsApproved, user.IsLockedOut,user.CreationDate,
            user.LastLoginDate,user.LastActivityDate,user.LastPasswordChangedDate,user.LastLockoutDate)
        {}

        public string Forename
        {
            get;set;
        }

        public string Surname
        {
            get;set;
        }

        public string Phone
        {
            get;set;
        }

        public string PropertyNameNumber
        {
            get;set;
        }

        public string Street
        {
            get; set;
        }

        public string Town
        {
            get; set;
        }

        public string Area
        {
            get; set;
        }

        public string Postcode
        {
            get; set;
        }

        public DateTime? ExpiredDate
        {
            get; set;
        }
    }

4 个答案:

答案 0 :(得分:1)

你认为你可以幽默我,并重写你的代码看起来像这样:

UserRepository userRepository = new UserRepository();
// retrieve custom user objects 
List<QUser> Users = userRepository.GetAllUsers().ToList();
// just get usernames only
List<string> userList = (from u in Users select u.UserName).ToList();
/* snip */
// set usernames to data source for a DropDownList
Username.DataSource = userList.ToArray(); // Cast error occurs here
Username.DataBind();

然后查看您的异常发生的位置。我很想知道该代码是否会更早发生异常。它可能会对问题提供一些见解。

答案 1 :(得分:1)

我只是在我的机器上运行你的代码并且看起来都很好 - 即使没有强制转换并移除ToArray()并且一切正常:

Default.aspx的

....
<div>
    <asp:DropDownList id="Username" runat="server"></asp:DropDownList>
</div>
....

Default.aspx.cs

public class UserRepository
{
    private List<QUser> AllUsers = new List<QUser>();
    public UserRepository()
    {
        //MyProvider is just a dummy class that inherits 
        //MembershipProvider and has the name "MyProvider"
        //We can use this to spoof the MembershipProviderCollection
        //and create new membership users on the fly.
        MembershipProvider mp = new MyProvider(); 
        MembershipProviderCollection mpc = Membership.Providers;

        //Override the private field _ReadOnly so we can add our
        //spoof provider to the provider collection.  In normal
        //circumstances your provider should be added through web.config
        //this is a dirty hack and should not be used in production code
        Type t = mpc.GetType();
        Type tbt = t.BaseType; //The _ReadOnly field is on the base type
        FieldInfo fi = tbt.GetField("_ReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
        fi.SetValue(mpc, false);

        //Add our spoof provider... if you don't add the spoof provider
        //then when we create a new user with the provider "MyProvider"
        //everything will fall to pieces...
        mpc.Add(mp);

        //Add a bunch of test users
        AllUsers.AddRange(new[] {
            new QUser(new MembershipUser("MyProvider", "User 1", 1, "user1@someco.com", "What is your question?", "Some random comment", true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue)),
            new QUser(new MembershipUser("MyProvider", "User 2", 2, "user2@someco.com", "What is your question?", "Some random comment", true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue)),
            new QUser(new MembershipUser("MyProvider", "User 3", 3, "user3@someco.com", "What is your question?", "Some random comment", true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue))
        });
    }
    public IEnumerable<QUser> GetAllUsers()
    {
        return AllUsers;
    }
}
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        UserRepository userRepository = new UserRepository();
        IEnumerable<QUser> Users = userRepository.GetAllUsers();
        IEnumerable<string> userList = (from u in Users select u.UserName);

        Username.DataSource = userList;
        Username.DataBind();
    }
}

我唯一的想法是你正在使用的DropDownList实际上不是下拉列表?或者你的ASP.NET开发服务器还有一些东西。您是否尝试过杀死它并重新启动它以确保它能正常工作?

答案 2 :(得分:0)

您是否'手动'将控件绑定到MemberShipUser类型?或者,此控制数据源的预期类型可能不是“字符串”而是“MemberShipUser”,并且在运行时检查此类以保留通用.DataSource接口...?

答案 3 :(得分:-1)

如果u.UserName对象实际上是MembershipUser类型,那么它本身不会返回用户名。

您必须使用u.UserName.UserName(实际用户名属性)或使用LINQ查询中的u.UserName.ToString()将其显式转换为字符串。

如果是这种情况,我会考虑重构Quser类并为UserName属性提供更准确的名称。