Ошибка загрузки сторонней DLL из приложения Asp.Net

ситуация довольно сложная (и мой английский очень простой), но давайте попробуем объяснить:

Я разрабатываю веб-службу Asp.net, вызывающую метод из внешней dll.

Эта внешняя dll вызывает некоторый метод из других .net dll.

Итак, у нас есть:

Asp.net WS ----> External.dll ----> other.NEt.Dll(---> other .netdll)

Вы должны знать, что внешняя dll использует путь (заданный методом инициализации) для разрешения своей внутренней ссылки.

В заключение у меня есть веб-приложение с добавленной ссылкой на мою External.dll и полностью доверенный путь ( c:\EXTERNAL ), полный всех .net dll, необходимых для external.dll.

Оглядевшись, я нашел этот код для добавления в application_START:

Dim path As String = String.Concat(System.Environment.GetEnvironmentVariable("PATH"), ";", "c:\EXTERNAL)
    System.Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Machine)

это добавит мой c:\EXTERNAL в глобальную среду PATH.

С этой конфигурацией, запущенной с сервера разработки Visual Studio, я не получаю ошибок, и все работает правильно.

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

Failure reading <Myobject> control of <(static)> type
Unable to create <myobject> object (<C:\(WRONGPATH)\needed.net.dll> assembly)

Чтобы решить эту проблему, я попытался добавить необходимые библиотеки .net в /bin моего приложения в wwwroot, но результат примерно такой:

Failure reading <MyType> control of <Myobject> type
Error returned by .NET Framework: 
System.ArgumentException: Un oggetto di tipo 'ComNet.BaseControl.LoginDisplayLayout' non può essere convertito nel tipo 'ComNet.BaseControl.LoginDisplayLayout'.
   in System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   in System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   in System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   in System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   in CDotNetType.bSetProperty(CDotNetType* , Object gcrObj, SByte* pszNom, CSLevel* pclPile, Int32 nDimension, Int32* pnTabDimension, STOperationDotNet* pstOperation)

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

Вот и все. Мне трудно объяснить этот dll-ад, но в основном я хотел бы воспроизвести то, что происходит, когда приложение хорошо работает на сервере разработки Visual Studio. Я также читал, что IIS не разрешает добавленный PATH без перезагрузки, поэтому я попытался добавить c:\external вручную в PATH и перезагрузиться, но появляются те же ошибки.

Спасибо за чтение, я надеюсь, что кто-то может помочь.

(извините за грамматические или орфографические ошибки! (я итальянец..))

Никола


person NicolaCasolari    schedule 19.02.2011    source источник


Ответы (1)


Попробуйте поместить все внешние .NET dll в каталог bin вашего веб-сайта.

Когда вы добавляете ссылку в Visual Studio на отдельную библиотеку или проект, она обычно копирует библиотеки DLL из этого проекта в каталог BIN вашего веб-сайта, но не всегда захватывает файлы DLL, от которых зависит этот проект.

Итак, если: yourwebsite.dll --> helper.dll --> helperComponent.dll --> widget.dll (где --> является ссылкой), при сборке только helper.dll оказывается в каталоге bin рядом с вашим веб-сайтом. dll. Как правило, вы хотите, чтобы все они были в одном месте. Тогда вам не придется беспокоиться о своем пути или о чем-то подобном.

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

Это было довольно хорошее чтение об организации проекта. Раздел «Копировать локально» играет роль в этом. Вы можете настроить xcopy в своих событиях Post Build, чтобы поместить эти ссылки 2-го и 3-го уровня в каталог bin под файлом решения.

http://www.simple-talk.com/dotnet/.net-framework/partitioning-your-code-base-through-.net-assemblies-and-visual-studio-projects/

person scottt732    schedule 19.02.2011
comment
Привет, спасибо за информацию, я пытался добавить все dll в папку \bin, но получаю ошибку, описанную в моем ответе, где похоже, что загружается одна и та же dll, но из другого места, что вызывает конфликты. Последняя надежда - gacutil. Странно то, что невозможно воспроизвести то, что работает на сервере разработки Visual Studio. - person NicolaCasolari; 21.02.2011
comment
Если сборка установлена ​​в глобальном кэше сборок, а ваша ссылка относится к строго типизированной сборке, она загрузит сборку из GAC, а не из вашего каталога bin. Посмотрите в файле .csproj в Блокноте ссылки, которые выглядят следующим образом: ‹Reference Include=AjaxControlToolkit, Version=3.0.11119.25533, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e,processorArchitecture=MSIL›... Если да, посмотрите, иметь соответствующую запись в GAC, используя gacutil /l AjaxControlToolkit из командной строки VS. Если есть, попробуйте удалить все после имени сборки из ссылки. - person scottt732; 22.02.2011