Реализация пользовательского удостоверения и IPrincipal в MVC

У меня есть базовое бета-приложение MVC 2, в котором я пытаюсь реализовать собственные классы Identity и Principal.

Я создал свои классы, реализующие интерфейсы IIdentity и IPrincipal, создал их экземпляры, а затем назначил объект CustomPrincipal моему Context.User в Application_AuthenticateRequest файла Global.asax.

Все это удается, и объекты выглядят хорошо. Когда я начинаю отображать представления, страницы теперь не работают. Первая ошибка возникает в представлении LogoOnUserControl по умолчанию в следующей строке кода:

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

Если я вытащу это, это приведет к ошибке в другой строке кода «Html.ActionLink».

Я получаю следующее сообщение об ошибке:

Исключение типа System.Runtime.Serialization.SerializationException произошло в WebDev.WebHost40.dll, но не было обработано в пользовательском коде.

Дополнительная информация: тип не разрешен для элемента Model.Entities.UserIdentity, Model, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null.

Есть ли какие-то дополнительные свойства, которые мне нужно реализовать в моем удостоверении, чтобы использовать настраиваемое удостоверение в MVC? Я попытался реализовать [Serializable ()] в классе Identity, но это не помогло.

ОБНОВЛЕНИЕ. Я пробовал 3–4 альтернативных способа реализовать это, но все равно не с той же ошибкой. Если я использую классы GenericIdentity / GenericPrincipal напрямую, это не вызывает ошибки.

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

Но это ни к чему не приводит, поскольку я пытаюсь использовать CustomIdentity для хранения нескольких свойств. Если я реализую интерфейсы IIdentity / IPrincipal или унаследую GenericIdentity / GenericPrincipal для своего CustomIdentity / CustomPrincipal, произойдет сбой с исходной ошибкой, указанной выше.


person Jay    schedule 10.12.2009    source источник
comment
Re: голосование "за" ... Вы тоже сталкиваетесь с подобной проблемой?   -  person Jay    schedule 11.12.2009


Ответы (3)


Я понял это с небольшой помощью из Интернета :) Хитрость в том, что вам нужно реализовать интерфейс ISerializable в своем классе, который реализует IIdentity. Надеюсь, это поможет кому-то еще сэкономить время :)

Объявление класса:

[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

Вот ссылка на статью с более подробной информацией. на «Особенность»

person Jay    schedule 11.12.2009
comment
эта функция - bs ... она существует с 2006 года и до сих пор влияет на меня с моим приложением asp.net mvc-3. - person Shawn Mclean; 12.01.2011
comment
Это решило мою проблему. То же самое и с IPrincipal. - person magnus; 18.01.2011
comment
почему вы создали новый GenericIdentity вместо CustomIdentity в вашем коде DeSerialization? = ›` GenericIdentity gIdent = new GenericIdentity (...) '?? - person Pure.Krome; 21.03.2011
comment
Сразу хотел заметить, что между System.ISerializable и System.Runtime.Serialization.ISerializable есть разница. Некоторое время я боролся с первым, прежде чем понял, что второй (System.Runtime.Serialization.ISerializable) мне нужен. - person sǝɯɐſ; 14.10.2014

У меня такая же проблема. Я решил это, переместив свое главное создание из 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;
            }
        }
    }
person Frank    schedule 10.12.2010

Со мной это работает, когда я наследую свой класс Identity от MarshalByRefObject.

Также обратите внимание: при использовании Linq-to-Sql проблем не возникло. Я переключился на Entity-Framework и бац, я получил сообщение выше.

person GvS    schedule 09.07.2010
comment
stackoverflow.com/ questions / 6503380 / подробнее о marshalbyrefobject - person Sergey; 31.01.2012