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" %>
Config
Мой 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
true и false и той же проблемой.
- Я также попытался остановить веб-сайт, удалить все временные файлы, повторно открыть и снова появился.
- Я попытался поместить мьютексы на global.asax, когда приложение начинает блокировать только одну компиляцию в то время, но это также не удается.
- С момента, когда это работает, тогда все хорошо, но если не работает, то не исправляется автоматически.
- Код, загружающий этот настраиваемый элемент управления, существует и вызывается в нескольких местах кода на разных страницах.
- Другие пользовательские элементы управления с аналогичной нагрузкой не имеют проблем.
- ViewState отключен для этого настраиваемого элемента управления.
- Я также пытаюсь переместить некоторый код, сменить полный вызов функции с помощью микро оптимизаций, снова не сработает.
-
Работает отлично на компьютере разработки. Я помещаю batch="true"
в web.config, и ошибка появляется сразу.
- Других подобных проблем нет, таких как ошибка, которую мы не можем исправить независимо от того, что. Система запускается в течение нескольких дней, пул НЕ перерабатывается, память стабильна, и есть больше свободного использования. Программа запускается уже много лет, но мы меняемся почти каждый день с обновлениями.
- В рамках одного и того же кода ядра работает более одного сайта (что-то вроде stackexchange), и все они имеют одну и ту же случайную проблему.
- Ошибка AutoEventWireup
- Он появляется и на другом настраиваемом элементе управления, который я загружаю таким же образом.
Что я делаю сейчас в качестве обходного пути при появлении этой ошибки: я просто заставляю проект перекомпилировать с небольшим изменением, и ошибка исчезнет до следующего обновления.
У меня есть ошибка, которая пытается решить последние недели дерева без причины. Я стараюсь почти все, что могу, но все не удается, и ошибка появляется снова. Поэтому я публикую здесь, может быть, некоторые могут помочь мне и найти выход из этого.
Последнее слово: эта ошибка сумасшедшая, пользовательский элемент управления один и тот же, я делаю что-нибудь на нем Я загружаю его только динамически и бум, у компилятора есть по два раза по разному, что только он знает - случайным образом.
Обновление 1
Мне удалось воспроизвести ошибку на машине разработчика. Там я обнаружил, что два модуля dll, которые содержат этот настраиваемый элемент управления, отличаются.
Один из них представлял собой набор из 4 пользовательских элементов управления. Другим модулем был только пользовательский контроль.
Обход
После недель дерева, пытающихся исправить эту ошибку, я заканчиваю тем, что эта ошибка появляется, когда компилятор выполняет пакетную компиляцию каталога и связывает множество разных настраиваемых элементов управления в одной и той же DLL. Поэтому, когда я пытаюсь загрузить его в одиночку, это исключение.
Поэтому я перемещаю проблемный пользовательский элемент управления только в другом каталоге и, кажется, сейчас его избегаю.
Обновление 2
Появляется снова, даже после перемещения некоторых файлов в другой каталог. Является случайным и не может найти четкую связь с тем, что вызывает его.
Обновление 3
Поскольку у нас есть точка, главная проблема здесь - пакетный компилятор (batch="true"
), который скомпилирует в одной и той же DLL многие пользовательские элементы управления, один из способов сказать компилятору НЕ делать это, это maxBatchGeneratedFileSize
. Я использую его со значением 100, и проблема появляется снова, теперь я опустил ее до 40 и проверил ее.
maxBatchGeneratedFileSize="40"
Ответы
Ответ 1
Это может произойти, если вы включили пакетную обработку, и на уровне каталога есть какая-то форма циклических ссылок.
Обратите внимание на этот ответ, чтобы точно понять, что я подразумеваю под "циркулярными ссылками" в этом контексте, поскольку значение довольно тонкое.
Если вам удастся сломать цикл (например, перемещая элемент управления пользователя в другом месте), вы не столкнетесь с этой проблемой.
Обновление 1
Я думаю, что теоретически это может быть вызвано только циклом, но иногда их трудно обнаружить.
Я дам вам альтернативное решение, которое, как я думаю, будет работать, и его очень легко попробовать (хотя это немного взломать). В пользовательском элементе управления, который создает проблемы, добавьте в директиву следующий атрибут:
<%@ Control Language="C#" [...] CompilerOptions="/define:dummy1" %>
Если вы видите это с некоторыми другими элементами управления, вы можете добавить одно и то же, но с dummy2, dummy3 и т.д.
Это приведет к тому, что пакет не будет управлять этим одним пользовательским элементом управления, поскольку он имеет разные потребности в компиляции от других. Технически вы можете добавить любую часть командной строки С# в качестве CompilerOptions
, но манекен /define
является самым простым и безопасным.
Но в отличие от выключения дозирования в глобальном масштабе, первичное воздействие будет минимальным, так как только очень небольшое подмножество страниц не будет выгружено.
BTW, само собой разумеется, что то, что вы видите, является ошибкой в ASP.NET, и эта ошибка существует там, вероятно, еще 10 лет! Может быть, в какой-то момент он должен быть адресован:)
Ответ 2
Чтобы отслеживать причину проблемы, я считаю, что важно знать, как был создан ваш контроль. Пожалуйста, обратитесь к этому чтению: Включение пользовательского элемента .ascx в Распространяемый пользовательский контроль.
Шаг 1: Создание пользовательского элемента управления
Чтобы авторизовать пользовательский элемент управления, лучше всего начать с пустого приложения, которое не содержит ничего, кроме ascx. Хотя авторское право пользователя контроль использует "стандартные" методы, существуют некоторые ограничения, которые вам нужно быть в курсе, чтобы он был успешно превращен в автономный пользовательский контроль. Основное ограничение состоит в том, что пользовательский элемент управления должен быть автономным. То есть, это не может зависеть от глобальных приложений приложения например App_Code или global.asax. Причина этого в том, что поскольку Цель состоит в том, чтобы превратить UserControl в автономную DLL, перерыв в других приложениях, если он полагался на код, который не является частью этого DLL. Одно исключение из этого правила заключается в том, что UserControl может быть в зависимости от сборок, которые находятся в каталоге bin (или в GAC). Вам просто нужно убедиться, что остальные сборки всегда доступный при использовании пользовательского элемента управления в других приложениях.
и
Шаг 3: Используйте команду публикации для предварительной сборки сайта
(...) Выберите "Использовать фиксированные имена и отдельные узлы". Это будет гарантировать, что ваш пользовательский контроль будет скомпилирован в один сборка, которая будет иметь имя, основанное на файле ascx. Если вы не проверьте этот параметр, ваш пользовательский элемент управления можно скомпилировать вместе с другие страницы и пользовательские элементы управления (если они есть), а сборка получит случайное имя, с которым было бы труднее работать.
По-моему, очень вероятно, что пользовательский контроль скомпилирован и зарегистрирован в GAC как отдельная сборка, а также включен в DLL вашего веб-приложения.
Примечание. Возможно, это должен был быть комментарий, но я хотел включить цитаты из вышеупомянутой ссылки. Надеюсь, это будет полезно.
Ответ 3
После многого отладки на обновленном веб-сайте 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
Ответ 4
Недавно я столкнулся с подобной проблемой, когда компилировал измененную версию asp.net MVC 4 и импортировал новую DLL в проект.
Как-то я ссылался на старые версии DLL в файле web.config(включая файл web.config в папке views)
Ошибка в моем случае была брошена, потому что две библиотеки DLL были разными версиями. 4.0.0 и 4.1.0.
Может быть, вы должны изучить это.
Может быть, указать версию скомпилированных файлов (я угадываю DLL)
Надеюсь, это поможет вам решить проблему.
Другие советы: Я предполагаю, что у вас есть какая-то система контроля версий? если да, верните все изменения до этого, и внимательно посмотрите на код и какие модели/элементы управления меняются и как.
если вы не используете VCS... вы не можете сделать, чтобы отменить изменения. И вы должны начать использовать VCS.
Ответ 5
Я заметил, что иногда дизайнер создает второй файл конструктора CodeBehind, например:
OneProduct_MediumImage.ascx
OneProduct_MediumImage.ascx.cs
OneProduct_MediumImage.ascx.designer.cs
OneProduct_MediumImage.ascx.designer1.cs
Вы не заметите, если у вас нет опции "Показать все файлы" в наборе решений Solution, но для веб-проекта компилятор будет компилировать все файлы в папке, а не только те, которые включены в проект.
Во-вторых, если ваш проект является "Проектом веб-сайта", нет пространств имен, что может привести к множеству странных ошибок. Посмотрите на этот вопрос: Проблема с пространством имен .net
Наконец, мне удалось решить кажущиеся случайные ошибки UserControl, установив атрибут ClassName
в файл управления, например:
<%@ Control Language="cs"
AutoEventWireup="false"
CodeBehind="OneProduct_MediumImage.ascx.cs"
Inherits="ASP.Modules_OneProduct_MedioumImage"
ClassName="OneProduct_MediumImageControl" %>