tags:

views:

413

answers:

4

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.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;
        }
    }
A: 

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.

MisterZimbu
u.UserName is not overriden by QUser and appears to be a string
Andi
Can you try doing u.ToString() instead and seeing what (if any) exceptions you get?
MisterZimbu
A: 

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... ?

Seb
+1  A: 

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.

Josh
My page load code only includes the line I have shown in the question, "/*snip */ was added by someone editing my question incorrectly.
Andi
I've rewritten the answer with another question :) Trying to get to the bottom of the issue. Do you think you could post the stacktrace of the error you are getting?
Josh
I've shuffled my code to use lists as it seemed more appropriate and it does work now but It was the restart of visual studio that fixed it - how annoying!
Andi
Yeah bugs like that are difficult to track down because it is the last thing you expect, or the first depending on how often it happens ;)
Josh
+1  A: 

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, "[email protected]", "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, "[email protected]", "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, "[email protected]", "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?

BenAlabaster
The restart fixed it , very frustrating when something like that happens, thank you +1
Andi