代码之家  ›  专栏  ›  技术社区  ›  Jay

在MVC中实现自定义标识和IPrincipal

  •  19
  • Jay  · 技术社区  · 16 年前

    我有一个基本的MVC2测试版应用程序,我正在尝试实现一个自定义的身份和主体类。

    我已经创建了实现IIdentity和IPrincipal接口的类,对它们进行了实例化,然后将CustomPrincipal对象分配给了Global.asax的应用程序_AuthenticateRequest中的Context.User。

    这一切都成功了,对象看起来不错。当我开始呈现视图时,页面现在失败了。第一个故障出现在以下代码行的默认LogonUserControl视图中:

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

    如果我把它拉出来,它就会在另一行“Html.ActionLink”代码中失败。

    类型的例外 'System.Runtime.Serialization.SerializationException' 在WebDev.WebHost40.dll中发生,但

    其他信息:类型不正确 已为成员解决 'Model.Entities.UserIdentity,Model, 版本=1.0.0.0,区域性=中性,

    为了在MVC中使用自定义标识,是否需要在标识中实现一些附加属性?我试图在Identity类中实现[Serializable()],但似乎没有效果。

    更新:

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

    但这对我来说毫无意义,因为我正试图使用CustomIdentity来保存一些属性。如果我为我的CustomIdentity/CustomPrincipal实现IIIdentity/IPrincipal接口或继承GenericEntity/GenericPrincipal,它将失败,并出现上述原始错误。

    3 回复  |  直到 16 年前
        1
  •  16
  •   Shawn Mclean    15 年前

    我在web上的一点帮助下解决了这个问题:)诀窍是必须在实现IIdentity的类中实现ISerializable接口。我希望这能帮别人节省一些时间:)

    [Serializable]
        public class ForumUserIdentity : IIdentity, ISerializable
    

    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
    

    这是你的电话号码 link to the article that has more detail on the "Feature"

        2
  •  11
  •   Frank    15 年前

    我也有同样的问题。我通过将我的主体创建从MVCAPApplication\u AuthenticateRequest移动到MVCAPApplication\u PostAuthenticateRequest解决了这个问题。

            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;
                }
            }
        }
    
        3
  •  4
  •   GvS    16 年前

    对我来说,当我从 MarshalByRefObject