Ошибка ASP.Net: «Тип« foo »существует в файлах« temp1.dll »и« temp2.dll »(часть 2) - PullRequest
13 голосов
/ 08 апреля 2010

Решение:

Я также переместил файлы ashx и asmx одновременно с этим. Атрибут Class директив WebService / WebHandler был указан в неправильном пространстве имен. Мораль этой истории заключается в том, чтобы убедиться, что вы просматриваете разметку для всех as*x файлов, для которых вы изменяете пространство имен, щелкнув по ним правой кнопкой мыши и выбрав «Просмотреть разметку».


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

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

Это говорит о том, что имя класса существует в двух файлах dll во временных файлах ASP.NET. Конечно, когда я открываю Reflector, он находится в двух библиотеках.

Если я переименую файл класса и ascx, все будет нормально. Ни в одном из файлов во всем моем приложении не используется оригинальное имя. Когда я переименовал файл, я открыл все файлы dll во временных файлах ASP.NET с помощью Reflector, и никаких ссылок на исходное имя класса не существует.

Так откуда взялась эта призрачная ссылка, как я могу это исправить?

Обновление: я буквально собрал все файлы в моем рабочем каталоге для решения и в своем временном каталоге для старого имени класса и удалил каждый файл, который его содержал. Затем я переименовал обратно в исходное сломанное имя и все еще получаю ошибку.

Ошибка сервера в «/» приложении. Ошибка компиляции Описание: An во время компиляции произошла ошибка ресурса, необходимого для обслуживания этого запрос. Пожалуйста, просмотрите следующее конкретные детали ошибки и измените ваш Исходный код соответственно.

Ошибка компилятора ssage: CS0433: Тип 'ASP.dashboard_badusercontrol_ascx' существует в обоих 'c: \ Docunts и Настройки \ я \ Local Настройки \ Temp \ Временный ASP.NET Файлы \ корень \ 3c2b7e1f \ 2e8a7620 \ App_Web_badusercontrol.ascx.a57ad085.iljdmp1p.dll» и 'c: \ Документы и настройки \ me \ Local Настройки \ Temp \ Временный ASP.NET Файлы \ корень \ 3c2b7e1f \ 2e8a7620 \ App_Web_bhdqaimy.dll '

Ошибка источника:

Строка 1098: Строка 1099:
[System.Diagnostics.DebuggerNonUserCodeAttribute ()] Линия 1100: частная глобальный :: ASP.dashboard_badusercontrol_ascx @__ BuildControlMyBadUserControl () { Строка 1101:
глобальный :: ASP.dashboard_badusercontrol_ascx @__ctrl; Строка 1102:

Исходный файл: c: \ Docunts и Настройки \ я \ Local Настройки \ Temp \ Временный ASP.NET Файлы \ корень \ 3c2b7e1f \ 2e8a7620 \ App_Web_foo.aspx.a57ad085.1nw6dais.0.cs Линия: 1100


Edit: Итак, я сделал еще несколько тестов на то, что работает и не работает. Допустим, исходное имя файла было «BadUserControl.ascx» в пространстве имен «MyNamespace».

Я переместил файл в каталог с именем «NewDirectory» и изменил пространство имен на «MyNamespace.NewDirectory». На моем жестком диске больше нет копий "BadUserControl.ascx". Я дважды проверил свою историю TFS, чтобы убедиться, что ЕДИНСТВЕННОЕ различие заключается в добавлении «.NewDirectory» к пространству имен в файлах разметки и кода кода.

Внутри этого пространства имен находятся два других пользовательских элемента управления с именами «OtherUserControl» и «AnotherUserControl».

Эта ситуация не срабатывает: У меня есть 2 директивы реестра:

<%@ Register src="BadUserControl.ascx" tagname="BadUserControl" tagprefix="uc1" %> 
<%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>

Эти ситуации работают:

  1. Я сохраняю имя BadUserControl.ascx как есть. У меня есть 1 директива Register на странице в том же пространстве имен:

    <%@ Register src="BadUserControl.ascx" tagname="BadUserControl" tagprefix="uc1" %>
    
  2. Я изменяю «BadUserControl.ascx» на «GoodUserControl.ascx» У меня есть 2 директивы реестра:

    <%@ Register src="GoodUserControl.ascx" tagname="GoodUserControl" tagprefix="uc1" %>
    <%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>
    
  3. 2 Зарегистрировать директивы без BadUserControl.ascx вообще:

    <%@ Register src="AnotherUserControl.ascx" tagname="AnotherUserControl" tagprefix="uc1" %>
    <%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>
    

Ответы [ 11 ]

15 голосов
/ 13 апреля 2010

ОБНОВЛЕНИЕ: хорошо, как вы обнаружили, циклическая ссылка была неправильным предположением, так как существуют другие ситуации, которые могут вызвать подобное поведение.

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

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

Что касается того, почему переименование файла исправило его, это может быть вызвано тем, что он изменил порядок обработки файлов, что является немного произвольным. Может случиться так, что если вы переименуете его во что-то другое, вы увидите, что это случится снова.

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


ОРИГИНАЛЬНЫЙ ОТВЕТ: Короче говоря, проблема в том, что когда пакетная обработка включена (и это по умолчанию), вы должны избегать циклических зависимостей на уровне каталогов. Позвольте мне объяснить, что я имею в виду под этим.

Вот пример. Скажем, у вас есть:

  • В папке 1: page.aspx и uc2.ascx
  • In forder2: uc1.ascx

И скажем, что page.aspx ссылается на uc1.ascx (через директиву @register), а uc1.ascx ссылается на uc2.ascx. На уровне файлов это прекрасно, но на уровне каталогов существует круговая зависимость: папка 1 ссылается на что-то в папке 2, которая ссылается на что-то в папке 1.

Почему это проблематично, связано с тем, как работает пакетирование: когда вы запрашиваете страницу, она сначала пытается скомпилировать все в папке folder1. Но так как folder1 / page.aspx ссылается на folder2 / uc1.ascx, он должен скомпилировать folder2, прежде чем он сможет сделать folder1. Но тогда uc1 использует uc2, то есть сначала он должен сделать folder1! На этом этапе ASP.NET обнаруживает ситуацию и пытается извлечь из нее выгоду, откомпилировав uc2.asc самостоятельно. Хотя это позволяет работать некоторым сценариям, оно также может вызывать странные вещи, потому что некоторые элементы в конечном итоге скомпилированы в две сборки. Здесь uc2.ascx будет скомпилирован как сам, так и с пакетом folder1.

Существует способ легко определить, есть ли у вашего сайта такие циклические зависимости на уровне папок. В окне консоли VS перейдите в корень сайта и запустите:

aspnet_compiler -v foo -p .

Если у вас круговые зависимости на уровне папок, вы получите несколько ошибок, которые выглядят следующим образом:

/foo/Sub/UC1.ascx(2): error ASPPARSE: Circular file references are not allowed.

Дешевый способ избежать этой проблемы - это то, что вы уже знаете: отключить пакетирование. Теперь, по крайней мере, вы знаете, почему это работает:)

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

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

4 голосов
/ 08 апреля 2010

Чисто Temporary ASP.NET Files. Может случиться так, что управление перед перемещением имеет сборку, а после - еще одну

3 голосов
/ 12 апреля 2010

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

2 голосов
/ 12 апреля 2010

Я думаю, что некоторые из этих ответов могли быть ошибочными. Я видел это, когда ваш программный код ссылается на другую версию сборки, чем ваш web.config. e.g.:

(версия 1.1.0.0 указана в aspx и 1.2.0.0 указана в web.config)

MyFile.aspx

<%@ Register TagPrefix="cc1" Namespace="StrongNamed.Namespace" Assembly="StrongNamed, Version=1.1.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" %>

web.config:

<assemblies>
    <add assembly="StrongNamed, Version=1.2.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"/>
...

Я видел случаи, когда, если обе версии сборки находятся в GAC, ASP.NET выдаст вам описанную ошибку.

2 голосов
/ 12 апреля 2010

В вашем решении более одного проекта?

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

Кроме того, взгляните на свои ссылки - может быть, вы дублируете определение того, на что ссылались?* Это дикий выстрел - но, может быть, у вас установлен этот .dll в GAC?

2 голосов
/ 08 апреля 2010

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

1 голос
/ 15 июля 2012

Попробуйте удалить все файлы и папки в папке «Temporary ASP.Net Files», она находится по этому пути:

c: \ windows \ Microsoft.NET \ Framework \ v2.0.50727 \ Временные файлы ASP.NET

это сработало для меня

1 голос
/ 05 июля 2011

Я столкнулся с этой проблемой, по крайней мере, дважды.
Ответ Дэвида Эббо определенно объясняет, что происходит.

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

public partial class CustomerAppointmentList : System.Web.UI.UserControl
{
}

Обратите внимание, что этот элемент управления не находится ни в каком пространстве имен.

В коде «customer.aspx.cs» я загружаю этот usercontrol динамически:

{
    var contentControl = (CustomerAppointmentList)LoadControl("../controls/customerappointmentlist.ascx");
}

Поскольку класс «CustomerAppointmentList» не существует на странице aspx, я должен ссылаться на негов моем custmer.aspx:

<%@ Reference Control="../controls/customerappointmentlist.ascx" %>

Когда компилятор asp.net должен скомпилировать customer.aspx, он попадет через класс CustomerAppointmentList и добавит тип в библиотеку для этой папки.
Через несколько секунд компилятор asp.net добавит класс «CustomerAppointmentList» в другую библиотеку для папки «controls».

После добавления интерфейса «ICustomerAppointmentList» во внешнюю библиотеку (projectname.web.dll) и внесения поправоккод, проблема ушла.Итак:

  1. Удалите часть «Ссылка» в файле aspx.
  2. Создайте интерфейс для своего пользовательского элемента управления.
  3. Убедитесь, что класс «CustomerAppointmentList» наследуетиз пользовательского элемента управления.
  4. При использовании LoadControl приведите к интерфейсу, который вы только что создали.

Мой новый код (ascx.cs):

    public partial class CustomerAppointmentList : System.Web.UI.UserControl, ICustomerAppointmentList
{
}

(aspx.cs)

{
var contentControl = (ICustomerAppointmentList)LoadControl("../controls/customerappointmentlist.ascx");  
}
1 голос
/ 12 апреля 2010

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

Чтобы увидеть, действительно ли это проблема,Я просматриваю все свои файлы кода - .cs и .designer.cs - и удаляю ВСЕ объявления пространства имен, а затем перестраиваю все, чтобы посмотреть, решит ли это проблему.

Вы не упоминаете, какая версияVisual Studio и .net, которые вы используете, тоже могут помочь - я помню, как сталкивался с подобной проблемой в VS2005.

1 голос
/ 12 апреля 2010
  • Закройте все запущенные экземпляры Visual Studio.
  • Остановите IIS (если запущен, иначе остановите эту вещь "devserver")
  • Очистить папку ASP.NET Temp (полностью)
  • Очистить папку BIN
  • Запустить IIS (если работает)
  • Старт VS
  • Восстановление решения
...