2009-12-10 11 views
19

Ho un'app di base MVC 2 beta in cui sto cercando di implementare una classe Identity e Principal personalizzata.Implementazione di un'identità personalizzata e IPrincipal in MVC

Ho creato le mie classi che implementano le interfacce IIdentity e IPrincipal, le ho istanziate e quindi assegnato l'oggetto CustomPrincipal al mio Context.User in Application_AuthenticateRequest del Global.asax.

Tutto questo ha esito positivo e gli oggetti sembrano buoni. Quando inizio a eseguire il rendering delle viste, le pagine non stanno funzionando. Il primo errore è nella visualizzazione predefinita LogoOnUserControl nella seguente riga di codice:

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

Se tiro questo fuori non riesce quindi su una diversa "Html.ActionLink" linea di codice.

L'errore che ricevo è:

Un'eccezione di tipo 'System.Runtime.Serialization.SerializationException' verificato in WebDev.WebHost40.dll ma non è stata gestita nel codice utente

Informazioni aggiuntive: il tipo non è risolto per il membro 'Model.Entities.UserIdentity, Model, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null'.

Esistono alcune proprietà aggiuntive che devo implementare nella mia identità per poter utilizzare un'identità personalizzata in MVC? Ho provato ad implementare [Serializable()] nella classe Identity ma non sembra avere un impatto.

UPDATE: Ho provato 3-4 modi alternativi di implementarlo ma non riesco ancora con lo stesso errore. Se uso direttamente le classi GenericIdentity/GenericPrincipal non fa errore.

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

Ma questo mi porta da nessuna parte poiché sto cercando di utilizzare il CustomIdentity per tenere un paio di proprietà. Se si implementano le interfacce IIdentity/IPrincipal o si eredita GenericIdentity/GenericPrincipal per CustomIdentity/CustomPrincipal, l'errore originale sopra riportato non riesce.

+0

Re: voto up ... Sei anche vedendo un problema simile? – Jay

risposta

16

L'ho capito con un piccolo aiuto dal web :) Il trucco è che devi implementare l'interfaccia ISerializable nella tua classe che implementa IIdentity. Spero che questo aiuta salvare qualcun altro po 'di tempo :)

dichiarazione Classe:

[Serializable] 
    public class ForumUserIdentity : IIdentity, ISerializable 

Implementazione per 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 

Ecco la link to the article that has more detail on the "Feature"

+0

questa funzione è bs ... è in circolazione dal 2006 e mi riguarda ancora con la mia applicazione asp.net ** mvc-3 **. –

+0

Questo ha risolto il mio problema. La stessa cosa vale per IPrincipal. – magnus

+0

perché hai creato un nuovo 'GenericIdentity' invece di un' CustomIdentity' nel tuo codice DeSerialization? => 'GenericIdentity gIdent = new GenericIdentity (...) '?? –

4

Con me sembra funzionare quando eredito la mia classe Identity da MarshalByRefObject.

Nota: quando si utilizza Linq-to-Sql non si sono verificati problemi. Sono passato a Entity-Framework e bang, ho ricevuto il messaggio sopra.

+1

http://stackoverflow.com/questions/6503380/how-expensive-is-using-marshalbyrefobject-compared-to-serialization c'è di più su marshalbyrefobject – Sergey

11

Ho avuto lo stesso problema. Ho risolto il problema spostando la mia principale creazione da MvcApplication_AuthenticateRequest a MvcApplication_PostAuthenticateRequest. Non so perché/come, ma ha risolto il problema :)

 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

Questo funziona. –

Problemi correlati