2009-12-10 7 views
19

J'ai une application bêta MVC 2 de base dans laquelle j'essaie d'implémenter des classes Identity et Principal personnalisées.Implémentation d'une identité personnalisée et d'IPrincipal dans MVC

J'ai créé mes classes qui implémentent les interfaces IIdentity et IPrincipal, les instancié puis assigné l'objet CustomPrincipal à mon objet Context.User dans Application_AuthenticateRequest de Global.asax.

Tout cela réussit et les objets ont l'air bien. Lorsque je commence à rendre les vues, les pages sont à présent défaillantes. Le premier échec est dans la vue LogoOnUserControl par défaut sur la ligne de code suivante:

[ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ] 

Si je tire ceci il échoue sur une ligne « Html.ActionLink » différent du code.

L'erreur je reçois est:

Une exception de type 'System.Runtime.Serialization.SerializationException' produite dans WebDev.WebHost40.dll mais n'a pas été traité dans le code utilisateur

Informations supplémentaires: Type n'est pas résolu pour le membre 'Model.Entities.UserIdentity, Model, Version = 1.0.0.0, Culture = neutre, PublicKeyToken = null'.

Y a-t-il des propriétés supplémentaires que je dois implémenter dans mon identité afin d'utiliser une identité personnalisée dans MVC? J'ai essayé d'implémenter [Serializable()] dans la classe Identity mais cela n'a pas semblé avoir un impact.

MISE À JOUR: J'ai essayé 3-4 manières alternatives d'implémenter ceci mais échoue toujours avec la même erreur. Si j'utilise les classes GenericIdentity/GenericPrincipal directement, cela ne fait pas erreur.

GenericIdentity ident = new GenericIdentity("jzxcvcx"); 
GenericPrincipal princ = new GenericPrincipal(ident, null); 
Context.User = princ; 

Mais cela me mène nulle part depuis que je suis en train d'utiliser le CustomIdentity pour tenir quelques propriétés. Si j'implémente les interfaces IIdentity/IPrincipal ou hérite de GenericIdentity/GenericPrincipal pour mon CustomIdentity/CustomPrincipal, il échoue avec l'erreur d'origine ci-dessus.

+0

Re: vote up ... Voyez-vous aussi un problème similaire? – Jay

Répondre

16

J'ai figuré celui-ci avec un peu d'aide du Web :) L'astuce est que vous devez implémenter l'interface ISerializable dans votre classe qui implémente IIdentity. J'espère que cela aide sauver quelqu'un d'autre quelque temps :)

déclaration de classe:

[Serializable] 
    public class ForumUserIdentity : IIdentity, ISerializable 

mise en œuvre pour ISerializable:

#region ISerializable Members 

     public void GetObjectData(SerializationInfo info, StreamingContext context) 
     { 
      if (context.State == StreamingContextStates.CrossAppDomain) 
      { 
       GenericIdentity gIdent = new GenericIdentity(this.Name, this.AuthenticationType); 
       info.SetType(gIdent.GetType()); 

       System.Reflection.MemberInfo[] serializableMembers; 
       object[] serializableValues; 

       serializableMembers = FormatterServices.GetSerializableMembers(gIdent.GetType()); 
       serializableValues = FormatterServices.GetObjectData(gIdent, serializableMembers); 

       for (int i = 0; i < serializableMembers.Length; i++) 
       { 
        info.AddValue(serializableMembers[i].Name, serializableValues[i]); 
       } 
      } 
      else 
      { 
       throw new InvalidOperationException("Serialization not supported"); 
      } 
     } 

     #endregion 

Voici le link to the article that has more detail on the "Feature"

+0

cette fonctionnalité est bs ... il a été autour depuis 2006 et me touche encore avec mon application asp.net ** mvc-3 **. –

+0

Cela a résolu mon problème. La même chose vaut pour IPrincipal aussi. – magnus

+0

Pourquoi avez-vous créé un nouveau 'GenericIdentity' au lieu d'un' CustomIdentity' dans votre code DeSerialization? => 'GenericIdentity gIdent = new GenericIdentity (...) '?? –

4

Avec moi il semble fonctionner quand j'hérite de ma classe d'identité de MarshalByRefObject.

Notez également: lors de l'utilisation de Linq-to-Sql, il n'y avait aucun problème. Je suis passé à Entity-Framework et bang, j'ai eu le message ci-dessus.

+1

http://stackoverflow.com/questions/6503380/how-expensive-is-using-marshalbyrefobject-compared-to-serialization il y a plus sur marshalbyrefobject – Sergey

11

J'ai eu le même problème. Je l'ai résolu en déplaçant ma création principale de MvcApplication_AuthenticateRequest à MvcApplication_PostAuthenticateRequest. Je ne sais pas pourquoi/comment, mais il a résolu le problème :)

 void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e) 
    { 
     HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
     if (authCookie != null) 
     { 
      string encTicket = authCookie.Value; 
      if (!String.IsNullOrEmpty(encTicket)) 
      { 
       FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encTicket); 
       BiamedIdentity id = new BiamedIdentity(ticket); 
       GenericPrincipal prin = new GenericPrincipal(id, null); 
       HttpContext.Current.User = prin; 
      } 
     } 
    } 
+0

Celui-ci fonctionne. –

Questions connexes