0

J'utilise le SqlMembershipProvider par défaut, mais j'ai créé une classe MembershipUser personnalisée (SoeMembershipUser) car j'avais besoin d'une propriété "DisplayName". Tout ce que DisplayName fait est de regarder le nom d'utilisateur et le formater différemment.Impossible de convertir MembershipUser en classe personnalisée (ASP.NET)

Lorsque j'essaie de convertir un MembershipUser en utilisateur SoeMembershipUser, j'obtiens une exception InvalidCastException. L'erreur exacte est: "Impossible de convertir un objet de type 'System.Web.Security.MembershipUser' en type 'Soe.Tracker.SoeMembershipUser'."

Voici le code qui échoue:

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

J'ai aussi essayé CASTING plus tard comme ceci:

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

Voici la classe SoeMembershipUser: REMARQUE: je l'ai laissé les constructeurs au premier , mais les a ajoutés plus tard quand j'ai commencé à avoir des problèmes. Les ajouter n'a fait aucune différence.

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

Une idée de la raison pour laquelle cette distribution n'est pas valide? Suis-je en train de négliger quelque chose de simple?

+0

Pouvez-vous envoyer le message d'erreur de distribution valide? –

+0

J'ai ajouté le message d'erreur exact ci-dessus. La trace de pile ne montre rien hors de l'ordinaire. – Rick

Répondre

2

Vous essayez de tomber d'une base à une classe dérivée (alias une conversion rétrécie, comme d'un animal à un chien - mais pas tous les animaux est un chien). Créez une méthode d'extension, ToMembershipUser, qui effectuera la conversion puisque vous savez comment procéder et que le compilateur ne le fait pas.

+0

Comme alternative à une méthode d'extension, vous pouvez utiliser le mot clé 'explicite' C#, comme illustré ici: http://msdn.microsoft.com/en-us/library/xhbhezf4(v=VS.100).aspx – Antony

+0

Concernant "explicite": Il semble que je devrais ajouter l'opérateur explicite à la classe MembershipUser elle-même pour qu'elle soit utile dans ma situation (sauf si je lis la documentation erronée). – Rick

+0

Oui, vous avez raison - l'opérateur explicite ne fonctionnerait pas dans ce cas. Ma faute. Il suffit d'aller avec une fonction autonome ou une méthode d'extension. L'un ou l'autre devrait fonctionner. – Antony

2

Le problème est que vous utilisez le SqlMembershipProvider par défaut. Vous devrez créer un custom MembershipProvider.

Vous pouvez probablement vous débrouiller avec simplement étendre le SqlMembershipProvider sur les méthodes GetUser.

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); 
    } 
} 
+0

+1 - les deux vont beaucoup main dans la main :) –

+0

+1 Je suis d'accord que cela résoudrait probablement mon problème, mais ce n'est pas tout à fait aussi extensible que je le voudrais puisque je veux pouvoir Permuter les fournisseurs d'adhésion dans et hors des systèmes existants. Comme .NET n'autorise pas l'héritage multiple, cela entraînerait un problème même si j'ai hérité de MembershipProvider plutôt que de SqlMembershipProvider. – Rick

+0

@Rick Je vois que vous avez accepté l'autre réponse, donc je suppose que vous avez un plan. Bonne chance. – bendewey