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

Jay*_*Jay 19 iprincipal iidentity asp.net-mvc-2

我有一个基本的MVC 2 beta应用程序,我正在尝试实现自定义Identity和Principal类.

我创建了实现IIdentity和IPrincipal接口的类,实例化它们,然后将CustomPrincipal对象分配给Global.asax的Application_AuthenticateRequest中的Context.User.

这一切都成功,对象看起来很好.当我开始渲染视图时,页面现在失败了.第一个失败是在以下代码行的默认LogoOnUserControl视图中:

 [ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ]
Run Code Online (Sandbox Code Playgroud)

如果我把它拉出来,那么就会失败一个不同的"Html.ActionLink"代码行.

我收到的错误是:

WebDev.WebHost40.dll中出现"System.Runtime.Serialization.SerializationException"类型的异常,但未在用户代码中处理

附加信息:成员'Model.Entities.UserIdentity,Model,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'的类型未解析.

为了在MVC中使用自定义标识,我是否需要在Identity中实现一些其他属性?我试图在Identity类中实现[Serializable()]但它似乎没有影响.

更新: 我尝试了3-4种实现此方法的替代方法但仍然失败并出现相同的错误.如果我直接使用GenericIdentity/GenericPrincipal类,则不会出错.

GenericIdentity ident = new GenericIdentity("jzxcvcx");
GenericPrincipal princ = new GenericPrincipal(ident, null);
Context.User = princ;
Run Code Online (Sandbox Code Playgroud)

但是这让我无处可去,因为我试图使用CustomIdentity来保存一些属性.如果我实现了IIdentity/IPrincipal接口或继承了我的CustomIdentity/CustomPrincipal的GenericIdentity/GenericPrincipal,它将失败并显示上面的原始错误.

Jay*_*Jay 16

我想通过网络上的一点帮助来解决这个问题:)诀窍是你必须在你的类中实现IIdentity的ISerializable接口.我希望这有助于拯救别人一段时间:)

舱位声明:

[Serializable]
    public class ForumUserIdentity : IIdentity, ISerializable
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

以下是文章链接,其中详细介绍了"功能"


Fra*_*ank 11

我有同样的问题.我通过将我的主体创建从MvcApplication_AuthenticateRequest移动到MvcApplication_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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)