开发者

Unable to cast object of type 'System.String' to type 'System.Web.Security.MembershipUser'

I'm trying to get a list of usernames and bind them to a DropDownList and I must be missing a trick because I can't seem to cast it to the correct type. The code is below and the title is the error message I'm recieving.

EDIT - QUser inherits from 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();

I've also tried casting the IEnumerable using the cast method as follows with no luck:

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

EDIT:

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.IsLoc开发者_StackOverflow社区kedOut,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;
        }
    }


I just ran your code on my machine and all looks good - even without the cast and removing the ToArray() and all works fine:

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

My only thought therefore is that the DropDownList that you're using is not actually a drop down list? Or there's something up with your ASP.NET development server. Have you tried killing it and restarting it just to be sure it's all working properly?


Do you think you could humor me and rewrite your code to look like this:

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();

And see where your exception occurs then. I would be curious to see if the exception occurs sooner with that code. It might provide some insight into the problem.


Didn't you 'manually' bind the control to the MemberShipUser type ? Or maybe the expected type for this control datasource isn't "string" but "MemberShipUser", and this is checked at runtime to keep a generic .DataSource interface... ?


If the u.UserName object is actually a MembershipUser type, that alone won't return the user name.

You'll have to either use u.UserName.UserName (the actual user name property) or explicitly convert it to a string using u.UserName.ToString() in the LINQ query.

If that's the case, I would consider refactoring the QUser class and give the UserName property a more accurate name.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜