Подтвердить что ты не робот

InvalidCastException для двух объектов одного типа

У меня есть эта странная проблема, с которой я не могу справиться сам. Класс в модели моего mvp-проекта, разработанного как singleton, вызывает InvalidCastException. Источник ошибки найден в этой строке кода, где десериализованный объект присваивается переменной экземпляра класса: engineObject = (ENGINE)xSerializer.Deserialize(str); Он возникает, когда я пытаюсь добавить один из моих UserControls в форму или в другой UC. Во всех моих UC есть специальный ведущий, который обращается к вышеупомянутой переменной экземпляра одноэлементного класса. Это то, что я получаю при попытке добавить UC где-нибудь:

'System.TypeInitializationException: инициализатор типа для "MVP.Model.EngineData" сделал исключение. ---- > System.InvalidCastException: [A] Двигатель нельзя использовать для [B] Engine. Тип A берется из "MVP.Model, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null" в контексте "LoadNeither" в местоположении "[...]\AppData\Roaming\Microsoft\VisualStudio\9.0\ProjectAssemblies\uankw1hh01\MVP.Model.dll. Тип B начинается с "MVP.Model, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null" в контексте "LoadNeither" в местоположении "[...]\AppData\Roaming\Microsoft\VisualStudio\9.0\ProjectAssemblies\u_hge2de01\MVP.Model.dll"...

Итак, у меня есть две сборки, и они не доступны из моей папки проекта, а из папки VS temp? Я много искал и нашел только это: Исключение IronPython: [A] Личность не может быть передана персонажу [B]. Существует решение, но сначала это касается IronPhyton, а во-вторых, я не знаю, где его использовать в рамках моего проекта?

Было бы здорово, если бы я мог помочь мне здесь:-) ТНХ

4b9b3361

Ответ 1

Типы для каждой сборки; если "одна и та же" сборка загружена дважды, то типы в каждой "копии" сборки не считаются одинаковыми.

Эти проблемы обычно возникают, когда две сборки находятся в контекстах Load и LoadFrom. Смотрите

Разница между LoadFile и LoadFrom со сборками .NET?

и ссылку на блог suzcook для получения подробной информации по этому вопросу.

Кроме того, рассмотрите возможность использования программы просмотра журнала Fusion, чтобы помочь диагностировать проблему.

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

Ответ 2

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

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);

Скрытый в этом было следующее внутреннее исключение (это было связано с Microsoft Dynamics CRM 4.0, но могло иметь отношение ко всему)

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'.; 

Я просто удалил дубликат dll (в C:\Program Files\Microsoft CRM\Server\bin), и ошибка исчезла.

Ответ 3

Судя по контексту, в котором загружается сборка (контекст "LoadNeither" ), некоторые разработчики могут делать что-то вроде загрузки сборки, которая была внутренне упакована в качестве ресурса с вашим приложением. Если вы это сделаете, вы будете использовать обработчик событий AppDomain.CurrentDomain.AssemblyResolve, чтобы ваше приложение могло указать, где .NET должен получить любую конкретную сборку, которая ему нужна.

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

Мы видели экземпляры, в которых .NET будет вызывать ResolveEventHandler более одного раза для одной и той же DLL. Я не уверен, почему .NET иногда делает это (это произошло на некоторых машинах, но не на всех машинах). Но для решения проблемы нам необходимо было сохранить глобальный список дескрипторов для загруженных сборок, поэтому, если .NET захочет снова загрузить сборку, мы вернули дескриптор той же самой сборки, которая была первоначально загружена, вместо того, чтобы загружать другую копию в память.

Я включил код, который вызвал эту проблему, и заметки о том, как правильно ее обрабатывать.

    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;
    }

Ответ 4

Моя конкретная библиотека классов case, упомянутая в веб-приложении, была переименована и перестроена. Старая версия библиотеки все еще находилась в папке bin под старым именем. Структура загружает все содержимое папки bin (обе библиотеки) и испускает эту ошибку. Так происходит не только при явной загрузке узлов. Очевидным решением в моем случае является очистка папки bin.

Ответ 5

Я получил его, когда попытался изменить этот актерский состав:

var  t = (TeacherWebPages)Session["TeachersAD"];

На это:

var  t = Session["TeachersAD"] as TeacherWebPages;

Однако сборка/сеанс/memcache была другой, и данные не возвращались, но не возникало ошибок. Поэтому позже мне все равно приходилось удалять определенные временные файлы каждый раз, когда исходная страница менялась из папки, на которую она жаловалась, что потребовало от меня уничтожения процесса IIS из диспетчера задач. Или в моем случае я могу просто выйти из системы, и это очищает состояние сеанса.