2009-12-10 19 views
19

Tôi có một ứng dụng MVC 2 beta cơ bản, nơi tôi đang cố gắng triển khai một lớp Identity và Principal.Thực hiện một danh tính tùy chỉnh và IPrincipal trong MVC

Tôi đã tạo các lớp của mình triển khai giao diện IIdentity và IPrincipal, khởi tạo chúng và sau đó gán đối tượng CustomPrincipal cho Context.User của tôi trong Application_AuthenticateRequest của Global.asax.

Điều này tất cả đều thành công và các đối tượng trông đẹp. Khi tôi bắt đầu hiển thị Chế độ xem, các trang hiện không thực hiện được. Sự thất bại đầu tiên là trong giao diện LogoOnUserControl mặc định trên các dòng mã sau đây:

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

Nếu tôi kéo ra nó sau đó thất bại trên "Html.ActionLink" dòng khác nhau của mã.

Các lỗi tôi nhận được là:

Một ngoại lệ của loại 'System.Runtime.Serialization.SerializationException' xảy ra ở WebDev.WebHost40.dll nhưng không được xử lý theo mã người dùng

Thông tin bổ sung: Loại không phải là được giải quyết cho thành viên 'Model.Entities.UserIdentity, Model, Phiên bản = 1.0.0.0, Văn hóa = trung lập, PublicKeyToken = null'.

Có một số thuộc tính bổ sung mà tôi cần triển khai trong Danh tính của mình để sử dụng Nhận dạng tùy chỉnh trong MVC không? Tôi đã cố gắng để thực hiện [Serializable()] trong lớp Identity nhưng nó dường như không có tác động.

CẬP NHẬT: Tôi đã thử 3-4 cách khác để triển khai điều này nhưng vẫn không thành công với cùng một lỗi. Nếu tôi sử dụng GenericIdentity/GenericPrincipal lớp học trực tiếp nó không lỗi.

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

Nhưng điều này khiến tôi không nơi nào vì tôi đang cố gắng sử dụng CustomIdentity để giữ một vài thuộc tính. Nếu tôi thực hiện các giao diện IIdentity/IPrincipal hoặc kế thừa GenericIdentity/GenericPrincipal cho CustomIdentity/CustomPrincipal của nó, nó không thành công với lỗi ban đầu ở trên.

+0

Re: up vote ... Bạn cũng thấy một vấn đề tương tự? – Jay

Trả lời

16

Tôi đã tìm ra điều này với một chút trợ giúp từ trang web :) Bí quyết là bạn phải triển khai giao diện ISerializable trong lớp của bạn triển khai thực hiện IIdentity. Tôi hy vọng điều này sẽ giúp tiết kiệm một ai đó một thời gian :)

khai Class:

[Serializable] 
    public class ForumUserIdentity : IIdentity, ISerializable 

thực hiện cho 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 

Đây là link to the article that has more detail on the "Feature"

+0

tính năng này là bs ... nó được khoảng từ năm 2006 và vẫn ảnh hưởng đến tôi với ứng dụng asp.net ** mvc-3 ** của tôi. –

+0

Điều này giải quyết được vấn đề của tôi. Điều tương tự cũng xảy ra với IPrincipal. – magnus

+0

tại sao bạn tạo một 'GenericIdentity' mới thay vì' CustomIdentity' trong mã DeSerialization của bạn? => 'GenericIdentity gIdent = new GenericIdentity (...) '?? –

4

Với tôi nó dường như hoạt động khi tôi kế thừa lớp Identity của tôi từ MarshalByRefObject.

Cũng lưu ý: khi sử dụng LINQ-to-Sql không có vấn đề gì. Tôi chuyển sang Entity-Framework và bang, tôi nhận được thông báo trên.

+1

http://stackoverflow.com/questions/6503380/how-expensive-is-using-marshalbyrefobject-compared-to-serialization có nhiều hơn về marshalbyrefobject – Sergey

11

Tôi đã gặp vấn đề tương tự. Tôi giải quyết nó bằng cách di chuyển hiệu trưởng của tôi tạo ra từ MvcApplication_AuthenticateRequest để MvcApplication_PostAuthenticateRequest. Tôi không biết tại sao/như thế nào, nhưng nó đã giải quyết được vấn đề :)

 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

Công cụ này hoạt động. –

Các vấn đề liên quan