2010-03-23 33 views
19

Tôi có vấn đề lạ này mà tôi không thể xử lý bản thân mình. Một lớp trong mô hình dự án mvp của tôi được thiết kế như singleton gây ra một InvalidCastException. Nguồn lỗi được tìm thấy trong dòng mã này, nơi đối tượng deserialised được gán cho biến cá thể của lớp: engineObject = (ENGINE)xSerializer.Deserialize(str); Nó xảy ra bất cứ khi nào tôi cố gắng thêm một trong các UserControls của tôi vào một Biểu mẫu hoặc đến một UC khác. Tất cả các UC của tôi có một người trình bày đặc biệt truy cập vào biến cá thể được đề cập ở trên của lớp singleton. Đây là những gì tôi nhận được khi cố gắng thêm UC vào một nơi nào đó:InvalidCastException cho hai đối tượng cùng loại

'System.TypeInitializationException: Trình khởi tạo kiểu cho' MVP.Model.EngineData 'đã ném một ngoại lệ. ----> System.InvalidCastException: [A] Engine không thể được truyền tới [B] Engine. Loại A bắt nguồn từ 'MVP.Model, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' trong ngữ cảnh 'LoadNeither' tại vị trí '[...] \ AppData \ Roaming \ Microsoft \ VisualStudio \ 9.0 \ ProjectAssemblies \ uankw1hh01 \ MVP.Model.dll '. Loại B bắt nguồn từ 'MVP.Model, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' trong ngữ cảnh 'LoadNeither' tại vị trí '[...] \ AppData \ Roaming \ Microsoft \ VisualStudio \ 9.0 \ ProjectAssemblies \ u_hge2de01 \ MVP.Model.dll '...

Vì vậy, tôi bằng cách nào đó có hai hội đồng và họ không được truy cập từ thư mục dự án của tôi, nhưng từ một thư mục tạm thời VS? Tôi googled rất nhiều và chỉ tìm thấy điều này: IronPython Exception: [A]Person cannot be cast to [B]Person. Có một giải pháp được cung cấp, nhưng trước tiên nó liên quan đến IronPhyton và thứ hai tôi không biết sử dụng nó trong dự án của tôi ở đâu?

Nó sẽ chỉ là tuyệt vời, nếu u có thể giúp tôi ra ở đây :-) thx

+0

bất kỳ giải pháp nào ?? – Kiquenet

+0

Xem http://stackoverflow.com/questions/23255892/how-to-reproduce-invalidcastexception-when-binding-to-an-assembly-in-the-loadfro/23255893#23255893 –

Trả lời

16

loại đều là giá lắp ráp; nếu bạn có "cùng một" lắp ráp nạp hai lần, sau đó các loại trong mỗi "bản sao" của hội đồng không được coi là cùng loại.

Các sự cố này thường xảy ra khi hai hội đồng ở trong ngữ cảnh Tải và Tải từ. Xem

Difference between LoadFile and LoadFrom with .NET Assemblies?

và liên kết vào blog suzcook để biết chi tiết về vấn đề đó.

Ngoài ra, hãy cân nhắc sử dụng trình xem nhật ký tổng hợp để giúp chẩn đoán sự cố.

http://msdn.microsoft.com/en-us/library/e74a18c4%28VS.71%29.aspx

+0

hey eric, trước hết: cám ơn !!! bạn là người đầu tiên cung cấp cho tôi bất kỳ gợi ý nào khác và trợ giúp về trường hợp này. Tôi đã vội vã thông qua các bài báo (và sẽ đọc chúng một lần nữa), nhưng tôi đã có một câu hỏi: Tôi không tải bất kỳ hội đồng của bản thân mình trong mã. Tôi chỉ tham khảo các dự án và sau đó thêm một UC với sự giúp đỡ của nhà thiết kế đến một UC hoặc Form khác. Vì vậy, câu hỏi của tôi là, nơi tôi nên bắt đầu tìm kiếm những lỗi tải như vậy như IDE chăm sóc của tất cả các quá trình tải? – LLEA

+0

Tôi đã cố gắng sử dụng trình xem nhật ký tổng hợp, nhưng không thể nhìn thấy bất cứ điều gì (rất có thể bởi vì tôi đã không sử dụng đúng cách) .Bên cạnh đó, một lần nữa câu hỏi hữu ích như thế nào khi công cụ này xảy ra trước khi chạy? – LLEA

2

đặc biệt của tôi trường hợp - thư viện lớp được tham chiếu trong ứng dụng web được đổi tên và xây dựng lại. Phiên bản cũ hơn của thư viện vẫn còn trong thư mục bin dưới tên cũ. Khuôn khổ tải bất cứ thứ gì trong thư mục bin (cả hai thư viện) và phát ra lỗi này. Vì vậy, nó xảy ra không chỉ khi hội đồng được nạp một cách rõ ràng. Giải pháp rõ ràng trong trường hợp của tôi là dọn dẹp thư mục bin.

+0

Vì vậy, tức giận tôi đã không google này trước khi chi tiêu 2 giờ tôi không phải lãng phí gỡ lỗi và xử lý sự cố để tìm dòng mã kích hoạt ngoại lệ này. Một khi tôi tìm thấy dòng mã, nó đã ném một ngoại lệ mà không bị bắt trong Try/Catch ... Đã SO bối rối. Rất vui khi tôi tìm thấy câu trả lời của bạn. Cảm ơn @ M-Kay –

1

Tình huống của tôi liên quan đến hai bản sao của cùng một dll. Một là trong thư mục bin và một là trong một thư mục con của cùng một thư mục bin. Cả hai đều được nạp, ngạc nhiên một số điều đã làm việc tốt, nhưng một số điều không và đó là khi thông báo lỗi này xuất hiện:

System.InvalidOperationException; There was an error generating the XML document.; Source: System.Xml; TargetSite: Void Serialize(System.Xml.XmlWriter, System.Object, System.Xml.Serialization.XmlSerializerNamespaces, System.String, System.String); 

Ẩn trong này là một ngoại lệ bên trong sau (điều này là để làm với Microsoft Dynamics CRM 4.0, nhưng có thể liên quan đến bất kỳ điều gì)

System.InvalidCastException; [A]XXX.CRMCustomCode.YYY.CreateCompanyRequest cannot be cast to [B]XXX.CRMCustomCode.YYY.CreateCompanyRequest. Type A originates from 'XXX.CRMCustomCode, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadFrom' at location 'C:\Program Files\Microsoft CRM\Server\bin\assembly\XXX.CRMCustomCode.dll'. Type B originates from 'XXX.CRMCustomCode, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Program Files\Microsoft CRM\Server\bin\XXX.CRMCustomCode.dll'.; 

Tôi vừa xóa dll trùng lặp (trong C: \ Program Files \ Microsoft CRM \ Server \ bin) và lỗi đã biến mất.

1

Đánh giá theo bối cảnh trong đó hội nhập được tải (ngữ cảnh là "LoadNeither"), một số nhà phát triển có thể làm một việc như tải một gói lắp ráp nội bộ như một tài nguyên với ứng dụng của bạn. Nếu bạn làm điều này, bạn sẽ sử dụng trình xử lý sự kiện AppDomain.CurrentDomain.AssemblyResolve, để ứng dụng của bạn có thể chỉ định nơi .NET sẽ nhận được bất kỳ assembly cụ thể nào mà nó cần.

Câu trả lời của tôi sẽ không giải thích các mưu đồ về cách thực hiện điều đó - nhưng tôi đề cập đến vì quá trình này dẫn trực tiếp đến cùng lỗi chính xác mà áp phích gốc gặp phải. Như Eric Lippert đề cập đến, các loại là mỗi lần lắp ráp. Vì vậy, nếu bạn nạp một assembly riêng lẻ nhiều hơn một lần, cùng một lớp được định nghĩa sẽ xuất hiện như các lớp khác nhau - mặc dù kiểm tra bằng hình ảnh cho thấy chúng dường như giống nhau.

Chúng tôi đã thấy các trường hợp trong đó .NET sẽ gọi ResolveEventHandler nhiều lần cho cùng một DLL. Tôi không chắc chắn tại sao. NET đôi khi làm điều này (nó đã xảy ra trên một số máy, nhưng không phải tất cả các máy). Nhưng để giải quyết vấn đề, chúng ta cần giữ một danh sách toàn cục các chốt để nạp các assembly, để nếu .NET muốn nạp assembly lại, chúng ta trả về một assembly cho cùng Assembly đã nạp ban đầu, thay vì nạp một bản sao khác vào bộ nhớ .

Tôi đã bao gồm mã gây ra sự cố cho chúng tôi và ghi chú về cách xử lý đúng cách.

public void AppStartup (object sender, StartupEventArgs e) 
    { 
     AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 
    } 

    public System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
     string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", ""); 
     dllName = dllName.Replace(".", "_"); 

     if (dllName.EndsWith("_resources")) return null; 
     System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly()); 
     byte[] bytes = null; 
     try 
     { 
      bytes = (byte[])rm.GetObject(dllName); 
     } 
     catch (Exception ex) 
     { 
     } 
     if (bytes != null) 
     { 
      // the following call will return a newly loaded assembly 
      // every time it is called 
      // if this function is called more than once for the same 
      // assembly, you'll load more than one copy into memory 
      // this can cause the InvalidCastException 
      // instead of doing this, you keep a global list of loaded 
      // assemblies, and return the previously loaded assembly 
      // handle, instead of loading it again 
      return System.Reflection.Assembly.Load(bytes); 
     } 
     return null; 
    } 
+0

Giải pháp của bạn đã giúp tôi tiết lộ rằng tôi đã tải một hội đồng nhiều lần và nhận được ngoại lệ "LoadNeither" InvalidCastException. Cảm ơn rất nhiều. –

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