webform tutorial net mvc entre ejemplos diferencias asp asp.net asp.net-mvc iis-7

asp.net - tutorial - webform mvc



¿Es posible un despliegue sencillo con aplicaciones ASP.NET MVC con componentes? (2)

Mi secuencia de comandos de implementación detiene el sitio web y muestra una página "Espere mientras se actualiza el sitio ...", que se renueva cada 15 segundos. Dado que la implementación demora menos de un minuto, parece solucionar el problema.

Probablemente no sea MVC específico, también podría aplicarse a los WebForms de ASP.NET, pero hasta ahora lo hemos experimentado en MVC2.

Cada vez que iniciamos la implementación remota con MSDeploy, recibimos una breve (5-6 segundos de) página de "error del servidor" para nuestras solicitudes hasta que se realice una nueva implementación. Aquí está el texto de error:

Error del servidor en la aplicación ''/''.

No se pudo cargar el archivo o ensamblado ''Some.Assembly'' o una de sus dependencias. El proceso no puede acceder al archivo porque lo está usando otro proceso. (Excepción de HRESULT: 0x80070020)

Descripción: se produjo una excepción no controlada durante la ejecución de la solicitud web actual. Revise el seguimiento de la pila para obtener más información sobre el error y dónde se originó en el código.

Detalles de la excepción: System.IO.FileLoadException: no se pudo cargar el archivo o ensamblado ''Some.Assembly'' o una de sus dependencias. El proceso no puede acceder al archivo porque lo está usando otro proceso. (Excepción de HRESULT: 0x80070020)

Información de la versión: Microsoft .NET Framework Version: 4.0.30319; Versión ASP.NET: 4.0.30319.1

Aquí están los rastros de pila que se muestran en la página de error:

[FileLoadException: Could not load file or assembly ''Some.Assembly'' or one of its dependencies. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)] System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0 System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +39 System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks) +132 System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +144 System.Reflection.Assembly.Load(String assemblyString) +28 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +46 [ConfigurationErrorsException: Could not load file or assembly ''Some.Assembly'' or one of its dependencies. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)] System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +618 System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +209 System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +130 System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +178 System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() +94 System.Web.Compilation.BuildManager.CallPreStartInitMethods() +332 System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +591 [HttpException (0x80004005): Could not load file or assembly ''Some.Assembly'' or one of its dependencies. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)] System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +8950644 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +256

El ensamblado que está causando esa falla (Some.Assembly) no es el ensamblado web real sino uno de los otros componentes debajo de sus "Referencias", firmado con .snk.

Después de 5-6 segundos, el sitio sube y el error desaparece.

Eso ciertamente no es el comportamiento deseado. Me pregunto si estamos haciendo algo mal en términos de cablear los componentes juntos. ¿Debería haber otro enfoque para garantizar un despliegue sin problemas? ¿O podría ser un error con MVC2?

La rotación superpuesta PS IIS está habilitada, de todos modos es la predeterminada.

Aquí están los componentes:

  • A.dll
  • Some.Assembly.dll (<--- este es el que falla, depende de A.dll)
  • B.dll (depende de A.dll y Some.Assembly.dll)
  • Web.dll (esta es la aplicación web, depende de todo lo anterior)

Todas las dependencias se establecen usando referencias regulares de ensamblado con Copy Local habilitado. Todos los dll son parte de la solución como proyectos separados.

MSDeploy solo despliega binarios, no el origen.


La rotación solapada solo se aplica al reciclaje de grupos y no tiene la intención de facilitar el tipo de implementación que está describiendo o requiriendo. Cuando la rotación superpuesta está habilitada, las solicitudes existentes en el proceso de trabajo "saliente" de la agrupación podrán completarse mientras que las nuevas solicitudes se enviarán al nuevo proceso de trabajo creado. Es un mecanismo para transferir elegantemente a un nuevo proceso de trabajo sin tirar de la alfombra debajo de las solicitudes existentes. Eso es todo lo que hace.

Las carpetas de instantáneas se usan para este propósito:

¿Para qué sirve la carpeta "Archivos temporales de ASP.NET"? (Mi respuesta)

De nuevo, no están destinados a proporcionar un mecanismo que facilite la ejecución de una base de códigos completa mientras carga un sitio nuevo.

Cuando implementa una aplicación ASP.NET, el sitio se comportará mal. Mientras está copiando sus ensamblajes, estos archivos serán bloqueados (probablemente exclusivamente) por cualquier proceso que maneje la carga (WebDAV o FTP).

Esto provoca las excepciones que ha observado y es más probable porque el mecanismo de copia oculta no puede leer los nuevos conjuntos hasta que se escriben (y WebDAV o FTP quita los bloqueos de escritura).

Además, las páginas que tienen dependencias en estos ensamblajes pueden no compilarse (ocultarse) si las firmas de método esperadas han cambiado o se han eliminado hasta que se hayan cargado las páginas correctas. O si las páginas / vistas se cargan primero y dependen de la funcionalidad en ensamblajes que aún no se han implementado, también obtendrá errores.

Todo el sitio estará en un estado incoherente hasta que se implemente el último archivo.

No hay un mecanismo incorporado en IIS para asegurar una implementación "atómica", es decir, cargar todas sus cosas y luego pasar a ejecutar eso. IIS seguirá atendiendo las solicitudes en el sitio y ASP.NET seguirá detectando los cambios de archivos a medida que carga la aplicación.

La única forma de implementar una aplicación sin generar estos errores es habilitar una página especial llamada App_Offline.htm antes de la implementación y luego renombrarla o eliminarla después de la implementación:

App_Offline.htm - Scott Guthrie
App_Offline.htm y trabajando en torno a la función "Errores amigables con IE"

También puede encontrar útil este artículo:

Cómo: Prepararse para implementar un proyecto web

Hay una alternativa un poco más complicada que implica tener dos carpetas, por ejemplo:

d:/websites/site/www-A d:/websites/site/www-B

El sitio en ejecución apunta a d:/websites/site/www-A , mientras tanto, despliega en d:/websites/site/www-B . Cuando esté listo, cambie el sitio a la carpeta d:/websites/site/www-B .

Cuando vengas a implementar el siguiente built, implementas en d:/websites/site/www-A y cambias a eso cuando estés satisfecho.

El inconveniente es que debe estar alerta y recordar qué carpeta es cuál.

Además, cualquier contenido subido por el usuario debería sincronizarse entre las dos carpetas (aunque podría tener una tercera carpeta asignada a un directorio virtual para cosas como esa).