19

我有一个基本的 MVC 2 beta 应用程序,我试图在其中实现自定义 Identity 和 Principal 类。

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

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

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

如果我把它拉出来,那么它会在不同的“Html.ActionLink”代码行上失败。

我收到的错误是:

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

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

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

更新: 我已经尝试了 3-4 种替代方法来实现这一点,但仍然失败并出现同样的错误。如果我直接使用 GenericIdentity/GenericPrincipal 类,它不会出错。

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

但这让我无处可去,因为我试图使用 CustomIdentity 来保存几个属性。如果我为我的 CustomIdentity/CustomPrincipal 实现 IIdentity/IPrincipal 接口或继承 GenericIdentity/GenericPrincipal ,则会出现上述原始错误。

4

3 回答 3

16

我在网络的帮助下想出了这个:) 诀窍是您必须在实现 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

这是文章的链接,其中包含有关“功能”的更多详细信息

于 2009-12-11T21:42:20.613 回答
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;
            }
        }
    }
于 2010-12-10T22:30:11.313 回答
4

对我来说,当我从MarshalByRefObject.

另请注意:使用 Linq-to-Sql 时没有问题。我切换到实体框架并砰的一声,我收到了上面的消息。

于 2010-07-09T15:36:47.477 回答