No se pudo cargar el tipo 'System.Runtime.CompilerServices.ExtensionAttribute' del ensamblado 'mscorlib

145

Al iniciar mi sitio web por primera vez, recibo este error

Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

¿Qué estoy haciendo mal?

Estoy usando .NET 4 y estoy iniciando el sitio desde Visual Studio.

Lo único que he cambiado recientemente es agregar Simple Injector (a través de Nuget) a mi proyecto.

Aquí está el rastro de la pila

[TypeLoadException: Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.]
   System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type) +0
   System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext) +180
   System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) +192
   System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg) +115
   System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent) +426
   System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType) +103
   System.Reflection.RuntimeAssembly.GetCustomAttributes(Type attributeType, Boolean inherit) +64
   WebActivator.AssemblyExtensions.GetActivationAttributes(Assembly assembly) +132
   WebActivator.ActivationManager.RunActivationMethods() +216
   WebActivator.ActivationManager.RunPreStartMethods() +43
   WebActivator.ActivationManager.Run() +69

[InvalidOperationException: The pre-application start initialization method Run on type WebActivator.ActivationManager threw an exception with the following error message: Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'..]
   System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods) +423
   System.Web.Compilation.BuildManager.CallPreStartInitMethods() +306
   System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +677

[HttpException (0x80004005): The pre-application start initialization method Run on type WebActivator.ActivationManager threw an exception with the following error message: Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'..]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +9090876
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97
   System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) +258

La primera línea de todas las vistas se resalta y cuando pasa el cursor sobre ellas, obtiene este error

The pre-application start initialisation method Run on type WebActivator.ActivationManager threw an exception with the following error message Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Sachin Kainth
fuente
1
Necesitamos más contexto sobre dónde está iniciando su sitio web y cómo. ¿Definitivamente estás usando .NET 4 / 4.5?
Jon Skeet
1
NB: si alguien tiene los mismos síntomas en la salida de su servidor de compilación, compruebe que tiene los ensamblados de referencia .net 4.0, después de instalar .net 4.5 deberá copiarlos desde su caja de desarrollo. Por lo general, están en algún lugar como: C: \ Archivos de programa (x86) \ Ensamblados de referencia \ Microsoft \ Framework \ .NETFramework \ v4.0 Para obtener más detalles, visite marcgravell.blogspot.co.nz/2012/09/…
Myster
1
Acabo de ver un problema similar con una DLL de .NET 4.5 que se usa como complemento para Microsoft Dynamics CRM 2011 en una máquina que solo tenía .NET 4.0. En lugar de rechazarlo directamente, lo registró y luego rompió por completo la personalización del flujo de trabajo (el complemento contenía una actividad de flujo de trabajo personalizada). Trace demostró que no podía encontrar ExtensionAttribute en mscorlib, me llevó aquí, lo reconstruyó para .NET 4.0 y resolvió el problema. Pensé que debería mencionarse para el futuro Google-fu.
Matthew Walton

Respuestas:

262

No se pudo cargar el tipo 'System.Runtime.CompilerServices.ExtensionAttribute' desde el ensamblado mscorlib

Sí, esto técnicamente puede salir mal cuando ejecuta código en .NET 4.0 en lugar de .NET 4.5. El atributo se movió de System.Core.dll a mscorlib.dll en .NET 4.5. Si bien eso suena como un cambio radical bastante desagradable en una versión de marco que se supone que es 100% compatible, se supone que un atributo [TypeForwardsTo] hace que esta diferencia no sea observable.

Como Murphy lo tendría, cada cambio bien intencionado como este tiene al menos un modo de falla en el que nadie pensó. Esto parece salir mal cuando se usó ILMerge para fusionar varios ensamblajes en uno y esa herramienta se usó incorrectamente. Un buen artículo de retroalimentación que describe esta ruptura está aquí . Se vincula a una publicación de blog que describe el error. Es un artículo bastante largo, pero si lo interpreto correctamente, la opción de línea de comando ILMerge incorrecta causa este problema:

  /targetplatform:"v4,c:\windows\Microsoft.NET\Framework\v4.0.30319"

Lo cual es incorrecto. Cuando instala 4.5 en la máquina que construye el programa, los ensamblados en ese directorio se actualizan de 4.0 a 4.5 y ya no son adecuados para apuntar a 4.0. Esas asambleas realmente ya no deberían estar allí, pero se mantuvieron por razones de compatibilidad. Los ensamblajes de referencia adecuados son los ensamblajes de referencia 4.0, almacenados en otro lugar:

  /targetplatform:"v4,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"

Entonces, las posibles soluciones son recurrir a 4.0 en la máquina de compilación, instalar .NET 4.5 en la máquina de destino y la solución real, para reconstruir el proyecto a partir del código fuente proporcionado, arreglando el comando ILMerge.


Tenga en cuenta que este modo de falla no es exclusivo de ILMerge, es solo un caso muy común. Cualquier otro escenario en el que estos ensamblajes 4.5 se usen como ensamblajes de referencia en un proyecto dirigido a 4.0 es probable que falle de la misma manera. A juzgar por otras preguntas, otro modo de falla común es en los servidores de compilación que se configuraron sin usar una licencia VS válida. Y pasando por alto que los paquetes de objetivos múltiples son una descarga gratuita .

El uso de los ensamblados de referencia en el subdirectorio c: \ archivos de programa (x86) es un requisito difícil. A partir de .NET 4.0, ya es importante evitar tomar accidentalmente una dependencia de una clase o método que se agregó en las versiones 4.01, 4.02 y 4.03. Pero absolutamente esencial ahora que se lanzó 4.5.

Hans Passant
fuente
31
Qué excelente respuesta.
Sachin Kainth
66
Tengo todos los mismos síntomas, pero no estoy usando ILMerge, ¿alguna pista? stacktrace aquí issues.umbraco.org/issue/U4-1708 , podría ser un archivo DLL de terceros o de terceros, pero ¿cómo lo encuentro?
Myster
3
Nota: es posible que no tenga una carpeta "C: \ Archivos de programa \ Ensamblados de referencia \ Microsoft \ Framework \ .NETFramework \ v4.0" en el caso de las versiones de Windows de 64 bits, en ese caso, compruebe si tiene un "C: \ Programa Archivos (x86) \ Assemblies de referencia \ Microsoft \ Framework \ .NETFramework \ v4.0 ".
Maarten Docter
3
No instalé ILMerge y tengo este problema, entonces, ¿cómo puedo solucionarlo? ¿Tengo que instalar .net 4.5 en el servidor de destino?
TamarG
44
Me desconcierta por qué todos siguen insistiendo en que esto es algo que la EM debería resolver. No lo harán, no pueden arreglar sus proyectos rotos o construir servidores. Utilice los ensamblajes de referencia correctos, problema resuelto.
Hans Passant
9

Tuve este problema, excepto que el tipo que no podía cargar era System.Reflection.AssemblyMetadataAttribute. La aplicación web se creó en una máquina con .NET 4.5 instalado (funciona bien allí), con 4.0 como marco de destino, pero el error se presentó cuando se ejecutó en un servidor web con solo 4.0 instalado. Luego lo probé en un servidor web con 4.5 instalado y no hubo ningún error. Entonces, como otros han dicho, todo esto se debe a la forma en que Microsoft lanzó 4.5, que básicamente es una actualización (y sobrescribir) de la versión 4.0. El ensamblado System.Reflection hace referencia a un tipo que no existe en 4.0 (AssemblyMetadataAttribute), por lo que fallará si no tiene el nuevo System.Reflection.dll.

Puede instalar .NET 4.5 en el servidor web de destino o compilar la aplicación en una máquina que no tiene 4.5 instalado. Lejos de una resolución ideal.

EricP
fuente
8

Tuve exactamente el mismo problema con un sitio (Kentico CMS), comencé el desarrollo en 4.5, descubrí que el servidor de producción solo admite 4.0, intenté volver al marco de destino de 4.0. Compilando las otras publicaciones en este hilo (específicamente se cambia el framework de destino a .Net 4 y .Net 4.5). Busqué a través de mi solución y descubrí que un puñado de los paquetes de NuGet todavía usaban bibliotecas con targetFramework = "net45".

packages.config (before):
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="AutoMapper" version="3.1.0" targetFramework="net45" />
  <package id="EntityFramework" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.0.0" targetFramework="net45" />
  <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
</packages>

Cambié el marco de destino de los proyectos a 4.5, eliminé todas las bibliotecas de NuGet, volví a 4.0 y volví a agregar las bibliotecas (tuve que usar algunas versiones anteriores que no dependían de 4.5).

packages.config (after):
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="AutoMapper" version="3.1.1" targetFramework="net40" />
  <package id="EntityFramework" version="6.0.2" targetFramework="net40" />
  <package id="Microsoft.AspNet.WebApi.Client" version="4.0.30506.0" targetFramework="net40" />
  <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net40" />
  <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
</packages>
vandsh
fuente
5

Hoy me encontré con este molesto problema. Usamos SmartAssembly para empacar / ofuscar nuestros ensambles .NET, pero de repente el producto final no funcionaba en nuestros sistemas de prueba. Ni siquiera pensé que tenía .NET 4.5, pero aparentemente algo lo instaló hace aproximadamente un mes.

Desinstalé 4.5 y reinstalé 4.0, y ahora todo vuelve a funcionar. No demasiado impresionado con haber pasado una tarde en esto.

Profesor1942
fuente
Advertencia anticipada para usted, INCLUSO SI resuelve el problema de otra manera, su versión ofuscada se volverá a romper, por lo que es posible que nunca sepa que la resolvió. Es decir, PUEDE construir en 4.5 e implementar sin problemas en máquinas de 4.0 solamente. Todo lo que fue necesario para mí fue el parche de objetivos múltiples que menciona Hans Passant. Al observar el manifiesto en ILDASM, pude ver que apuntaba correctamente a System.Core en lugar de mscorlib. Pero NO en la versión que se ejecutó a través de SmartAssembly (v5.5).
Josh Sutterfield
4

Encontré el mismo problema al intentar leer datos de una base de datos Firebird. Después de muchas horas de búsqueda, descubrí que el problema fue causado por un error que cometí en la consulta. Arreglarlo lo hizo funcionar perfectamente. No tenía nada que ver con la versión del Framework

usuario3036330
fuente
hombre, gracias, me encontré con el mismo problema, ¿cómo lo solucionaste?
Benny
3

Nos encontramos con este problema y lo rastreamos hasta el paquete Nucoet de Geocoding.net que estábamos usando para ayudarnos con nuestras vistas de Google Maps (Geocoding.net versión 3.1.0 publicada 2/4/2014).

El dll Geocoding parece ser .Net 4.0 cuando examina el archivo del paquete o lo ve usando la aplicación Dot Peek de Jet Brains; sin embargo, un colega mío dice que se compiló con ilmerge, por lo que probablemente esté relacionado con los problemas de ilmerge mencionados anteriormente.

Fue un largo proceso rastrearlo. Buscamos diferentes conjuntos de cambios de TFS hasta que lo redujimos al conjunto de cambios que agregó el paquete NuGet mencionado anteriormente. Después de eliminarlo, pudimos implementarlo en nuestro servidor .NET 4.

David Yates
fuente
En nuestro caso, el problema fue causado por Quartz.NET v2.3. La actualización a la versión 2.3.2 solucionó el problema.
Vértigo
2

En mi caso, después de degradar de .NET 4.5 a .NET 4.0, el proyecto funcionaba bien en una máquina local, pero fallaba en el servidor después de la publicación.

Resulta que ese destino tenía algunos ensamblajes antiguos, que todavía hacían referencia a .NET 4.5.

Se solucionó habilitando la opción de publicación "Eliminar todos los archivos existentes antes de publicar"

Alexander Puchkov
fuente
1

En mi caso, fue Blend SDK perdido en la máquina TeamCity. Esto causó el error debido a la forma incorrecta de resolver el ensamblaje.

Yury Schkatula
fuente
1

Solo agrego esta respuesta para ayudar a Google a ahorrar algo de tiempo las horas que he pasado para llegar aquí. Utilicé ILMerge en mi proyecto .Net 4.0, sin la opción / targetplatform establecida, suponiendo que se detectaría correctamente desde mi ensamblaje principal. Luego tuve quejas de los usuarios solo en Windows XP, también conocido como WinXP. Esto ahora tiene sentido ya que XP nunca tendrá> .Net 4.0 instalado, mientras que la mayoría de los sistemas operativos más nuevos sí. Entonces, si los usuarios de XP tienen problemas, consulte las soluciones anteriores.

LMK
fuente
1

En mi caso, tuve un problema relacionado con el uso de Microsoft.ReportViewer.WebForms. Eliminé validate = true de la add verblínea en web.config y comenzó a funcionar:

<system.web>
    <httpHandlers>
      <add verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
Matthew Lock
fuente