none
error al exportar archivo de excel en asp .net RRS feed

  • Pregunta

  • Buen día espero que me puedan ayudar con este detalle ya que tengo mucho tiempo y nada mas no doy con la solución

    tengo una aplicación hecha en C# .NET  la aplicación funciona perfectamente en mi maquina local , consiste en exportar un archivo de excel  para actualizar datos a una tabla de de BD (aqui todo bien el codigo funciona)

    el detalle es que al momento de probar la aplicación ya una vez estando en el servidor de producción, me muestra un error que es el siguiente al dar clic en el botón de exportar  

    error : no error message available, result code:E_ACCESSDENIED (0x80070005). de igual manera anexo imagen


    el servidor donde monto mi aplicación es un windows server 2016 64 bits  y es donde me sale ese error , cabe mencionar que desde que se migro el server si funcionaba en un windows server 2008 64 bits 

    jueves, 19 de marzo de 2020 4:50

Todas las respuestas

  • No se ve la imagen que dices que anexas. Pero por el mensaje que sale, es un problema de permisos. No se puede decir mucho más sin saber cuál es el mecanismo que usas para exportar y dónde exactamente sale el error.

    Si estás usando automatización OLE para enviarle comandos a un Excel (cosa que no deberías hacer en un servidor, esta técnica deberías reservarla solo para aplicaciones de escritorio), entonces muy posiblemente sea una falta de permisos en la configuración de DCOM.

    https://www.ryadel.com/en/office-interop-dcom-config-windows-server-iis-word-excel-access-asp-net-c-sharp/

    jueves, 19 de marzo de 2020 7:13
  • hola

    >>el detalle es que al momento de probar la aplicación ya una vez estando en el servidor de producción, me muestra un error

    No puedes usar las librerias de office en un ambiente web, por detras sigue usando libreria COM y eso es para dolores de cabeza

    recomendaria cambies el codigo al uso de librerias basadas en Open Xml como ser

    ClosedXML

    EPPlus

    o sino directo las librerias de open xml de office

    Introducción al SDK de Open XML 2.5 para Office

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 19 de marzo de 2020 13:07
  • Muchas Gracias por responder Alberto , anexo la parte de mi codigo donde hago el mecanismo de exportar el achivo de excel 


     

    private void CargaDatos() 
    {
    //Declara los controles
    OleDbConnection conexion = new OleDbConnection();
    DataSet datos = new DataSet();

    bool renglonValido = false;
    bool registros = false;

    //Se agrgan listas para guardar la ubicacion de los campos que no aprueben la validacion 
    ArrayList L1 = new ArrayList();
    ArrayList L2 = new ArrayList();


    //Toma el archivo de Excel Origen
    if(txtBuscar.PostedFile.FileName == "") 
    {
    MandaAlerta("Debe seleccionar un archivo a importar");
    }
    else
    {
    //Guarda el archivo de Excel en el Servidor Web

    string horas = "";
    string Destino = "";
    string nombreArchivo = "";  

    //Se elimina la condicion para que siempre se cree el archivo - JRMM - EISEI
    horas = System.DateTime.Now.ToShortTimeString();
    horas = horas.Replace(":","");
    horas = horas.Replace("AM","");
    horas = horas.Replace("PM","");
    horas=horas.Trim(); 
    nombreArchivo = "A" + System.DateTime.Today.ToString("yyMMdd")+ horas + this.txtBuscar.PostedFile.FileName.Substring(txtBuscar.PostedFile.FileName.LastIndexOf(@"\")+1);

    Destino = @"\..\Inetpub\wwwroot\exportar\Archivos\" + nombreArchivo;
    txtBuscar.PostedFile.SaveAs(Destino);


    // conexion para  leer archivos de excel 2007 
    conexion = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source='" + @Destino + " '; " + "Extended Properties=Excel 12.0 Xml;");
    try
    {
    conexion.Open();
    }
    catch
    {
    MandaAlerta("Debe proporcionar un archivo válido, AQUI SALE EL MENSAJE DE ERROR ");
    }

    jueves, 19 de marzo de 2020 18:34
  • Muchas Gracias Leandro 

    este es mi codigo aqui es donde me haces la observacion que necesito cambiar el codigo ? adicional anexo la imagen del error

    private void CargaDatos() 
    {
    //Declara los controles
    OleDbConnection conexion = new OleDbConnection();
    DataSet datos = new DataSet();

    bool renglonValido = false;
    bool registros = false;

    //Se agrgan listas para guardar la ubicacion de los campos que no aprueben la validacion 
    ArrayList L1 = new ArrayList();
    ArrayList L2 = new ArrayList();


    //Toma el archivo de Excel Origen
    if(txtBuscar.PostedFile.FileName == "") 
    {
    MandaAlerta("Debe seleccionar un archivo a importar");
    }
    else
    {
    //Guarda el archivo de Excel en el Servidor Web

    string horas = "";
    string Destino = "";
    string nombreArchivo = "";  

    //Se elimina la condicion para que siempre se cree el archivo - JRMM - EISEI
    horas = System.DateTime.Now.ToShortTimeString();
    horas = horas.Replace(":","");
    horas = horas.Replace("AM","");
    horas = horas.Replace("PM","");
    horas=horas.Trim(); 
    nombreArchivo = "A" + System.DateTime.Today.ToString("yyMMdd")+ horas + this.txtBuscar.PostedFile.FileName.Substring(txtBuscar.PostedFile.FileName.LastIndexOf(@"\")+1);

    Destino = @"\..\Inetpub\wwwroot\exportar\Archivos\" + nombreArchivo;
    txtBuscar.PostedFile.SaveAs(Destino);


    // conexion para  leer archivos de excel 2007 
    conexion = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source='" + @Destino + " '; " + "Extended Properties=Excel 12.0 Xml;");
    try
    {
    conexion.Open();
    }
    catch
    {
    MandaAlerta("Debe proporcionar un archivo válido, AQUI SALE EL MENSAJE DE ERROR ");
    }


    jueves, 19 de marzo de 2020 18:37
  • hola

    Al usar Microsoft.ACE.OLEDB.12.0 quizas debas instalar en engine

     Microsoft Access Database Engine 2016 Redistributable

    Ademas para obtener una ruta fisica del archivo se usa el Server.MapPath()

    string Destino = Server.MapPath("~/exportar/Archivos/" + nombreArchivo);

    no aplican las rutas relativas usando ..\ ni nada de eso, tiene que ser una ruta fisica

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    jueves, 19 de marzo de 2020 19:12
  • Destino = @"\..\Inetpub\wwwroot\exportar\Archivos\" + nombreArchivo;

    Esto puede ser terriblemente problemático. Fíjate que has escrito una ruta que empieza por "\", cosa que indica que es una ruta absoluta partiendo de la raiz. Y luego pone ".." que indica "subir un nivel hacia arriba". Pero esto es imposible si ya te encuentras en el nivel más alto como indica la primera "\".

    Una vez que corrijas la ruta y pongas una ruta válida (preferiblemente usando MapPath como ya te han sugerido en otra respuesta), el segundo tema que tienes que comprobar es que en la ruta que hayas seleccionado tiene que tener permiso de lectura y escritura la cuenta bajo la que se ejecuta la aplicación. Esta cuenta es la que se indica en el Pool de Aplicaciones de IIS que hayas asignado a esta aplicación. De forma predeterminada y si no la cambias es una cuenta de sistema que normalmente no tiene permiso de escritura sobre las carpetas que cuelgan de Inetpub. Se lo puedes conceder, desde luego, o puedes cambiar la cuenta del Pool, pero mientras no lo cambies dará errores de "acceso denegado" al acceder al archivo.

    Ten en cuenta que cuando lo pruebas en tu máquina local no rueda con la cuenta de servicio, sino con tu cuenta de usuario, por lo que sí que tiene permiso de acceso y no se presenta este problema. Pero cuando lo instalas en un IIS en producción, los permisos son mucho más limitados mientras no los cambies.

    jueves, 19 de marzo de 2020 20:43
  • que tal Leandro buen día gracias por tu respuesta y apoyo

    sobre la observación que me comentaste del Microsoft Access Data Base Engine , ya lo tengo instalado en el servidor como comente anteriormente es windows server 2016 64 bits 

    también modifique la ruta de acceso al archivo la modifique y la hice así :

    destino = Server.MapPath("/exportar/archivos/" + NombreArchivo);

    solo que me sigue saliendo el mismo error que les comentaba E_ACCESSDENIED(0x80070005). que es lo que me estar faltando 

    muchas gracias por el apoyo

    viernes, 20 de marzo de 2020 17:17
  • que tal Alberto gracias por tu apoyo y respuesta

    te comento  modifique la ruta del archivo: destino = Server.MapPath("/exportar/archivos/" + NombreArchivo);

    Me podrías apoyar un poco mas en la posible solución que me comentas sobre darle permisos de lectura y escritura a la ruta del archivo 

    donde encuentro la cuenta que ejecuta la aplicación para poderle dar permiso, por mas que le busco no le encuentro 

    saludos y muchas gracias por el apoyo  

    viernes, 20 de marzo de 2020 17:26
  • [...] el Microsoft Access Data Base Engine , ya lo tengo instalado en el servidor [...] es windows server 2016 64 bits [...] me sigue saliendo el mismo error que les comentaba E_ACCESSDENIED [...] que es lo que me estar faltando

    Muy probablemente lo que te esté faltando sea ajustar los permisos de DCOM. En una respuesta anterior ya te puse un enlace a un artículo que explica cómo configurarlos.

    Ojo con el tema de que el servidor sea de 64 bits, no vaya a ser que tengas instalado un Access de 32 bits. De ser así, tendrías que forzar a la aplicación web a rodar en 32 bits (desde las propiedades del Pool en IIS).

    viernes, 20 de marzo de 2020 17:49
  • Me podrías apoyar un poco mas en la posible solución que me comentas sobre darle permisos de lectura y escritura a la ruta del archivo [...] donde encuentro la cuenta que ejecuta la aplicación para poderle dar permiso, por mas que le busco no le encuentro

    De momento no te preocupes mucho por esto, porque hay otro problema previo que hay que resolver. Te está saliendo el error de que no se puede llamar a Excel debido a los permisos de DCOM. Mientras no consigas que se ejecute Excel, es inútil darle permiso para que pueda grabar el archivo (obviamente, si no se ejecuta no puede grabar nada).

    Lo de los permisos de DCOM es un poco complicadillo. Más vale buscar algún artículo que lo enseñe paso a paso y seguir todos los pasos. En una respuesta anterior te puse un enlace a uno de estos artículos, pero siempre puedes buscar otros.

    Una vez que eso esté resuelto, para dar permisos al archivo abre la aplicación de administración de IIS, busca el Pool de aplicaciones en el que instalaste la tuya, y en las propiedades avanzadas del Pool hay una entrada que es la cuenta que se usa para ejecutar la aplicación. Entonces vas al Explorador de Windows, buscas la carpeta deseada, y en Propiedades -> Seguridad añades permisos para la cuenta que copiaste desde las propiedades del Pool. Pero insisto, no te molestes en hacer esto mientras no hayas resuelto el tema del DCOM.

    Si te atascas en este tema de los permisos, y dado que esto ya no es un tema de programación sino de Administración de Sistemas, yo recomendaría preguntar en algún foro de IIS o de Windows, en donde cabe esperar que haya gente que lo tenga mucho más dominado que los simples desarrolladores que visitamos en estos foros de msdn.


    viernes, 20 de marzo de 2020 18:41
  • hola

    >>solo que me sigue saliendo el mismo error que les comentaba E_ACCESSDENIED(0x80070005). que es lo que me estar faltando

    Pero puedes observar que la ruta que genera es correcta ? lo pregunto porque no incluiste el ~/ con lo cual no defines la ruta relativa desde el root del sitio

    Valida ademas que el sitio web que configuras esta ejecutando con un usuario en el Application Pool que tiene acceso de escritura en esa carpeta

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 20 de marzo de 2020 18:51