InvalidCastException для объекта того же типа - Загрузка настраиваемого элемента управления

У меня очень зашитая ошибка, один из моих настраиваемых элементов управления кажется, что создает два скомпилированных файла, и когда я пытаюсь загрузить его динамически с LoadControl(), это просто сбой, потому что не могу передать одно другому - даже если они точно такие же . Пишу сообщение, чтобы убедиться, что все одинаково, только сменить скомпилированную dll.

System.Web.HttpUnhandledException (0x80004005):     
 Exception of type 'System.Web.HttpUnhandledException' was thrown. --->             
    System.InvalidCastException:
[A]ASP.Modules_OneProduct_MedioumImage cannot be cast to
[B]ASP.Modules_OneProduct_MedioumImage.         

   Type A originates from 'App_Web_kg4bazz1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
in the context 'Default'
    at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_kg4bazz1.dll'.          

   Type B originates from 'App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' 
in the context 'Default'    
    at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b.dll'.

Код

Это код в том виде, в каком он есть прямо сейчас, после того, как я следил за именно тем, что написано в MSDN:

foreach (int OneProductID in TheProductIdArrays)
{
    // here is the throw.
    ASP.Modules_OneProduct_MedioumImage OneProduct = 
        (ASP.Modules_OneProduct_MedioumImage)LoadControl(@"~/mod/OneProduct_MediumImage.ascx");

    // do some work with 
    //OneProduct
}

Раньше я загружал элемент управления без ASP., но после появления этой ошибки и поиска решения я строго слежу за тем, что есть в MSDN. Ошибка все еще существует, что бы я ни делал.

Я также пробовал оба этих метода, каждый по отдельности и вместе (снова неудачно)

<%@ Register src="~/mod/OneProduct_MediumImage.ascx" tagname="OneProduct_MediumImage" tagprefix="uc1" %>
<%@ Reference Control="~/mod/OneProduct_MediumImage.ascx" %>

Конфиг

Мой web.config, я пробовал использовать maxBatchSize 20, 100, 1000, а также optimizeCompilations true или false, но ошибка появляется снова.

<compilation debug="false" defaultLanguage="C#" batch="true"
maxBatchSize="800" batchTimeout="10800" optimizeCompilations="false"
targetFramework="4.0">

Теперь немного о

  • Ошибка случайная, в некоторых компиляциях появляется, в некоторых - нет.
  • Проект большой, страницы живут каждую минуту, и множество людей просят что-то показать, но появляются и тогда, когда внутри никого нет.
  • Работает на 64-битной dot.net 4, интегрированной
  • Запускается как веб-сад, но также протестирован и только один пул (и возникает та же проблема)
  • Сеанс отключен для всего проекта.
  • Страницы открываются с 2007 года, но эта проблема появляется в прошлом месяце, к сожалению, я не могу найти, где и как запускается, или что вызывает ее, потому что я опаздываю на несколько дней, чтобы ее увидеть.
  • Появляется только один загружаемый настраиваемый элемент управления, тот, у которого есть тяжелый вызов.
  • Я менял 4 раза код, внося небольшие изменения или большие изменения, но все еще там.
  • Я пытался с optimizeCompilations истиной и ложью и той же проблемой.
  • Я попытался также остановить Интернет, удалить все временные файлы, снова открыть, и снова было.
  • Я пытаюсь разместить мьютекс на global.asax, когда приложение начинает блокировать только одну компиляцию за раз, но это тоже не удается.
  • С того момента, как это работает, все в порядке, но если не работает, автоматически не исправляется.
  • Код, который я загружаю для этого настраиваемого элемента управления, существует и вызывается более чем в одном месте кода на разных страницах.
  • Остальные кастомные элементы управления, с аналогичной нагрузкой, проблем не возникли.
  • ViewState отключен для этого настраиваемого элемента управления.
  • Я также попытался переместить некоторый код, изменить полный вызов функции с помощью микрооптимизации, снова не потерпеть неудачу.
  • Нормально работает на компьютере разработчика. Я помещаю batch="true" в web.config, и ошибка появляется сразу.
  • Других проблем, подобных этой, вроде ошибки, которую мы не можем исправить ни на что, нет. Система работает несколько дней, пул вообще НЕ перерабатывается, память стабильна, есть больше свободного места. Программа работает уже много лет, но мы меняемся практически каждый день с обновлениями.
  • Под одним и тем же основным кодом работает более одного сайта (что-то вроде stackexchange), и у всех одна и та же случайная проблема.
  • AutoEventWireup является ложным
  • Он появляется и на другом настраиваемом элементе управления, который я загружаю таким же образом.

Что я делаю сейчас в качестве обходного пути, когда появляется эта ошибка: я просто заставляю проект перекомпилировать с небольшим изменением, и ошибка исчезает до следующего обновления.

У меня есть ошибка, которая пытается решить последние три недели, но не выясняет причину. Я пробовал почти все, что мог, но все терпит неудачу, и ошибка появляется снова. Так что я пишу здесь, может быть, кто-то может мне помочь и найти выход из этого.

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

Обновление 1

Мне удалось воспроизвести ошибку на машине разработчика. Там я обнаружил, что два модуля dll, которые содержат этот настраиваемый элемент управления, имеют разные.

Один представлял собой набор из 4 настраиваемых элементов управления вместе. Другой модуль был только настраиваемым элементом управления.

Обходной путь

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

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

Обновление 2

Появляется снова, даже после того, как я переместил некоторые файлы в другой каталог. Является случайным и не может найти четкой связи с тем, что его запускает.

Обновление 3

Поскольку мы заметили, что основной проблемой здесь является пакетная компиляция (batch="true"), которая компилирует на одной и той же dll множество настраиваемых элементов управления, один из способов сказать компилятору НЕ делать этого - это _ 12_. Я использую его со значением 100, и проблема появляется снова, теперь я уменьшил его до 40 и протестировал его.

maxBatchGeneratedFileSize="40"

person Aristos    schedule 10.02.2013    source источник
comment
Как я бы посоветовал вам попробовать batch = false и фиктивное редактирование и сохранение (как в stackoverflow.com/a/12476097/1236044 и stackoverflow.com/a/10212834/1236044), боюсь, у меня нет серьезного ответа на твоя проблема. Если вы можете, возможно, вы можете попробовать по своему желанию: - преобразовать этот единственный элемент управления в программный код - переместить элемент управления в ту же папку, что и все другие элементы управления и страницы, которые на него ссылаются   -  person jbl    schedule 05.03.2013
comment
@jbl Да, с batch = false все в порядке. Но опыт использования впечатляет ... потому что каждая некомпилированная страница заставит меня долго ждать, и, возможно, уйдет ...   -  person Aristos    schedule 05.03.2013
comment
@jbl Я также использую этот параметр maxBatchGeneratedFileSize, при пакетной компиляции пытаюсь сказать компилятору, чтобы он не объединял многие элементы управления вместе.   -  person Aristos    schedule 05.03.2013
comment
@ CapitanCavernícola Никакого обфускатора. То же самое происходит при отладке и при выпуске. В некоторых случаях я вызываю этот метод из PageLoad, в другом - из событий Init. Когда появляется эта ошибка, я получаю ее внутри цикла при каждом вызове (не только при первом), при каждом вызове на каждой странице.   -  person Aristos    schedule 05.03.2013
comment
@AlexFilipovici - это элемент управления пользователя, заканчивающийся на .ascs   -  person Aristos    schedule 07.03.2013


Ответы (5)


Это может произойти, если у вас включена пакетная обработка и есть некоторая форма циклических ссылок на уровне каталогов.

См. Этот ответ, чтобы понять, что я имею в виду. «круговыми ссылками» в этом контексте, поскольку значение довольно тонкое.

Если вам удастся разорвать цикл (например, переместив пользовательский элемент управления в другое место), вы не столкнетесь с этой проблемой.

Обновление 1

Я бы подумал, что теоретически это может быть вызвано только циклом, но иногда их бывает трудно обнаружить.

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

<%@ Control Language="C#" [...] CompilerOptions="/define:dummy1" %>

Если вы видите это с некоторыми другими элементами управления, вы можете добавить то же самое, но с dummy2, dummy3 и т. Д.

Это приведет к тому, что этот пользовательский элемент управления не будет пакетироваться, поскольку у него разные потребности в компиляции, чем у других. Технически вы можете добавить любую часть командной строки C # как CompilerOptions, но фиктивный /define является самым простым и безвредным.

Но в отличие от глобального отключения пакетной обработки, влияние на производительность будет минимальным, поскольку пакетирование не будет выполняться только для очень небольшого подмножества страниц.

Кстати, само собой разумеется, что то, что вы видите, является ошибкой в ​​ASP.NET, и эта ошибка существует уже более 10 лет! Может быть, в какой-то момент это следует решить :)

person David Ebbo    schedule 06.03.2013
comment
Я проверил и не нашел в файлах ссылки на цикл. Структура проекта большая, но правильно размещена в хорошем дереве без каких-либо ссылок на файловый цикл. Однако я перемещаю его только в каталог и все тот же. Проблема здесь в том, что компилятор добавляет его в dll вместе с некоторыми другими элементами управления, и когда я пытаюсь загрузить его вручную, просто происходит сбой, потому что создается новая dll. Еще один вариант - создать второй клон этого элемента управления и разместить его в двух местах вместе с разными именами, но это тоже не удается. - person Aristos; 07.03.2013
comment
Обратите внимание, что я говорю о циклических ссылках на уровне каталогов, а не на уровне файлов. Ответ, на который я указал, содержит более подробную информацию об этом. - person David Ebbo; 07.03.2013
comment
Да, я видел это, я не собираюсь отказываться от этого ответа, я проверю его еще раз и думаю еще раз. - person Aristos; 07.03.2013
comment
мои извинения, я просто понимаю, что вы являетесь частью команды asp.net. Еще раз спасибо за ответ. Я переместил файлы в разные каталоги, и каким-то образом они снова смешиваются с пакетом ... но нет циклической ссылки, они просто объединяют компиляцию, и когда я пытаюсь загрузить ее в одиночку, возникает эта ошибка. - person Aristos; 07.03.2013
comment
Я обновил свой ответ альтернативным решением, которое должно быть легко попробовать и, вероятно, будет работать. :) - person David Ebbo; 07.03.2013
comment
Я считаю, что это решает эту проблему, и это то, что я искал - и не знал об этом, я могу добавить другой CompilerOption в эту строку. Первые тесты кажется, что работает. - person Aristos; 08.03.2013
comment
Еще раз спасибо, это работает. Наслаждайтесь инструментами модератора :) stackoverflow.com/privileges/moderator-tools - person Aristos; 09.03.2013
comment
Вау, спасибо, я понятия не имел, что собираюсь обрести такие ужасающие способности! :) - person David Ebbo; 09.03.2013

Я считаю, что для того, чтобы отследить причину проблемы, важно знать, как был создан ваш контроль. См. Это чтение: Превращение пользовательского элемента управления .ascx в распространяемый настраиваемый элемент управления .

Шаг 1. Создание пользовательского элемента управления

Чтобы создать пользовательский элемент управления, лучше всего начать с пустого приложения, которое не содержит ничего, кроме ascx. Хотя при создании пользовательского элемента управления используются «стандартные» методы, существуют некоторые ограничения, о которых необходимо знать, чтобы его можно было успешно превратить в автономный настраиваемый элемент управления. Основное ограничение заключается в том, что пользовательский элемент управления должен быть автономным. То есть он не может зависеть от глобальных вещей приложения, таких как App_Code или global.asax. Причина этого в том, что, поскольку цель состоит в том, чтобы превратить UserControl в автономную DLL, он сломался бы в других приложениях, если бы полагался на код, который не является частью этой DLL. Единственным исключением из этого правила является то, что UserControl может зависеть от сборок, которые находятся в каталоге bin (или в GAC). Вам просто нужно убедиться, что другие сборки всегда доступны, когда вы используете свой настраиваемый элемент управления в других приложениях.

и

Шаг 3. Используйте команду публикации для предварительной компиляции сайта

(...) Выберите «Использовать фиксированные имена и одностраничные сборки». Это гарантирует, что ваш пользовательский элемент управления будет скомпилирован в единую сборку, имя которой будет основано на файле ascx. Если вы не отметите этот параметр, ваш пользовательский элемент управления может быть скомпилирован вместе с другими страницами и пользовательскими элементами управления (если они у вас есть), и сборка получит случайное имя, с которым будет труднее работать.

На мой взгляд, весьма вероятно, что пользовательский элемент управления скомпилирован и зарегистрирован в GAC как отдельная сборка, а также включен в DLL вашего веб-приложения.

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

person Alex Filipovici    schedule 07.03.2013
comment
Это хорошая идея / обходной путь, чтобы разделить его и предварительно перекомпилировать в качестве настраиваемого элемента управления вне проекта. - person Aristos; 07.03.2013
comment
@AlexFilipovici Другой ответ - решить проблему с минимальными изменениями, спасибо за ответ. - person Aristos; 09.03.2013

После долгой отладки на обновленном веб-сайте ASP.NET моей последней ошибкой была эта ошибка во время выполнения.

Я только что проверил опцию Build / Publish «использовать фиксированные имена и одностраничные сборки», и это решило мой случай :)

Вот несколько полезных ссылок: https://msdn.microsoft.com/en-us/library/hh475319(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/aa479044.aspx

http://forums.asp.net/t/960707.aspx

person DestyNova    schedule 14.02.2016
comment
не могли бы вы написать, где вы поместили эти параметры в web.config? - person Aristos; 15.02.2016
comment
В моем случае я использую ASP.NET WSP (ASPX). У меня есть французский VS, поэтому я надеюсь, что перевод соответствует истинному пункту меню: p Для сборки вы можете сделать это в меню веб-сайта, вы найдете параметры сборки (которые аналогичны страницам свойств, когда вы щелкаете правой кнопкой мыши по ваш веб-сайт в панели Обозревателя решений), а затем вы войдете в параметры MSBuild, вы найдете там 2 флажка. Для публикации, это на шаге Parameters, отметьте Precompile и войдите в configure; затем снимите флажок «Разрешить обновление предварительно скомпилированного веб-сайта» и выберите «Не объединять». Создайте отдельную сборку для каждой страницы и элемента управления. - person DestyNova; 15.02.2016

Я недавно столкнулся с подобной проблемой, когда компилировал модифицированную версию asp.net MVC 4 и импортировал новую DLL в проект.

Как-то я ссылался на старые версии библиотек DLL в web.config (включая web.config в папке представлений)

В моем случае ошибка возникла из-за того, что две библиотеки DLL были разных версий. 4.0.0 и 4.1.0. Может тебе стоит разобраться в этом. Может быть, укажите версию скомпилированных файлов (я предполагаю, что DLL)

Надеюсь, это поможет вам решить проблему.

другие советы: Я предполагаю, что у вас есть какая-то система контроля версий? если да, верните все изменения до того, как это началось, и внимательно посмотрите на код, а также на то, какие модели / элементы управления меняются и как. если вы не используете VCS ... вы мало что можете сделать, чтобы отменить изменения. И вам следует начать использовать VCS.

person Nikola Sivkov    schedule 04.03.2013
comment
Спасибо за ваш ответ. Здесь компиляция динамическая, ничего не делаю. Проблема, которую я заметил, заключается в том, что компилятор добавляет в одну DLL вместе более одного элемента управления. Теперь, когда я пытаюсь загрузить его динамически, создается еще одна dll, с одним элементом управления - и по какой-то причине возникает эта ошибка! - person Aristos; 05.03.2013
comment
Возможно ли, что существуют разные версии одного и того же объекта, который вы динамически компилируете? если да, то это может быть причиной проблемы. - person Nikola Sivkov; 05.03.2013
comment
У меня есть контроль версий, но изменений слишком много! Я имею ввиду слишком много. Однако я не уверен, связана ли проблема с кодом - возможно, связана с ростом проекта или даже с обновлением самой MS на сервере. - person Aristos; 05.03.2013
comment
Проблема здесь не в версии, а в одной DLL, содержащей более одного пользовательского элемента управления из пакетной компиляции, а вторая DLL содержит только один элемент управления. И это не работает вместе. Так что не версия. - person Aristos; 07.03.2013

Я заметил, что иногда дизайнер создает второй файл дизайнера CodeBehind, например, у вас будет:

OneProduct_MediumImage.ascx
OneProduct_MediumImage.ascx.cs
OneProduct_MediumImage.ascx.designer.cs
OneProduct_MediumImage.ascx.designer1.cs

Вы не заметите, если у вас нет опции «Показать все файлы» в обозревателе решений, но для веб-проекта компилятор скомпилирует все файлы в папке, а не только те, которые включены в проект.

Во-вторых, если ваш проект является «Проектом веб-сайта», там нет пространств имен, что может привести к множеству странных ошибок. Посмотрите на этот вопрос SO: Проблема пространства имен .net

Наконец, мне удалось решить кажущиеся случайными ошибки UserControl, установив атрибут ClassName в контрольном файле, например:

<%@ Control Language="cs" 
    AutoEventWireup="false" 
    CodeBehind="OneProduct_MediumImage.ascx.cs" 
    Inherits="ASP.Modules_OneProduct_MedioumImage"
    ClassName="OneProduct_MediumImageControl" %>
person Willem    schedule 07.03.2013
comment
Спасибо за ответ, я использую ClassName, я проверю остальное из того, что вы пишете. (Я опытный пользователь, я знаю и вижу все файлы на моем диске, скрытые, систему, всех, я ничего не пропускаю, и я никогда не использую проводник для управления файлами, кроме другой программы) - person Aristos; 07.03.2013
comment
Иногда мне просто нужно изменить ClassName на что-то случайное (просто добавить случайную букву или число) и ничего не менять, и вдруг элемент управления снова заработает. Потом при следующей сборке опять сломалось, поменял другую букву, исправил. Так и не понял, почему это происходит. - person Willem; 07.03.2013